Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
folgende Aufgabe bereitet mir seit Tagen Probleme.
Schreiben Sie eine Funktion hervorheben, die einen String zurückgibt, in dem alle eingeklammerten Teile eines übergebenen Springs durch Sperrdruck (ohne Klammern) hervorgehoben sind.
Ein (kleines) Beispiel, (ohne) Klammern!
Ein k_l_e_i_n_e_s Beispiel, o_h_n_e Klammern!
Lösungsansatz nicht vorhanden.
Ich weiss nicht wie ich nach der Klammern suchen soll.
@Sodenthaler: Der gezeigte Quelltext macht ja so gar keinen Sinn.
Wie würdest Du die Aufgabe denn von Hand lösen? Schreib das mal detailliert, in kleinen Schritten auf. Ausgangslage: Kästchenpapier mit dem Text „Ein (kleines) Beispiel, (ohne) Klammern!“ mit einem Buchstaben pro Kästchen in einer Zeile.
Was musst Du jetzt Schritt für Schritt tun um das Ergebnis in eine andere Zeile auf dem Blatt zu schreiben? Einfach Kästchen für Kästchen kopieren führt zwar in die Nähe des gewünschten Ergebnis, aber halt nicht ganz. Du musst ja bei jedem Kästchen entscheiden ob Du es kopierst oder nicht, und falls ja, ob Du nur das Kästchen kopierst, oder ob Du das Kästchen kopierst und das nächste leer lässt.
@heiner88: Dadurch das man die Hausaufgaben für andere löst, lernen die das nicht.
Sowas was du benutzt haben wir nicht in der Schule druchgenommen.
...Quellcode macht keinen Sinn.
Ich habe halt die Prüfungsaufgabe. Hier soll ich die Funktion hervorheben schreiben und am Ende soll print(hervorheben('Ein (kleines) Beispiel, (ohne) Klammern!')) stehen.
Wie ich vorgehe würde:
def hervorheben(s: str)->str: #so fängt die Funktion immer an
a=0 # ich benötige ja einen Laufindex
und ab da hab ich schon die Probleme
ich muss jetzt den string durchsuchen bis ich auf eine Klammer komme
while a<len(s):
und das Wort in der Klammer will ich mit '_'.join() als Sperrdruck ausgeben.
Ich hab halt Probleme mit den Indexen.
Ich kann mir das im Kopf nicht vorstellen wie ich damit arbeiten soll.
@Sodenthaler: wenn Ihr gelernt habt, Typ-Annotationen zu machen, dann ...
Man kann die Aufgabe auf verschiedene Arten lösen, entweder mit Zustandsautomaten, wie heiner88, oder mit regulären Ausdrücken (was ja intern auch nur ein Zustandsautomat ist) wie BlackJack. Wenn Ihr das nicht durchgenommen habt, bleibt halt noch die umständliche Methode irgendetwas mit Indizes zu machen. Und da ist ja Dein Ansatz schon gar nicht mal so schlecht. Nur willst Du wieder nach dem ersten Schritt die restlichen auf einmal machen, wobei dann eben dieser zweite Schritt viel zu groß ist.
Daher erst einmal nur den ersten Schritt: also wie sieht ein Programm aus, das eine öffnende Klammer in einem String sucht und dessen Index ausgibt?
Hi ich komm echt nicht drauf.
Wir haben sowas noch nie durchgenommen: Suche nach einer Klammer.
Ich habe hier z.B. eine Aufgabe wo ich nach 3 gleich Buchstaben suchen soll. Das konnte ich lösen. Aber wie ich auf die Klammer komme kp.
#def highlight (s: str)->str:
# i=0
# while i<len(s):
# j=i+1
# while j<len(s) and s[j].lower()==s.lower():
# j+=1
# if j-i>=3:
# s=s[:i]+s[i:j].upper() + s[j:]
# i=j
# return s
#s = 'Aaah, eine suuuuper Werkstatttreppe!!!'
#print(s)
#print(highlight(s))
Ich komm da echt nicht weiter.
def hervorheben(s: str)->str:
i=1
while i<len(s):# durchsuche den string
for i in s:
if i=='(':
@Sodenthaler: wie sucht man nach ( ? Das ist doch deutlich einfacher, als nach gleichen Buchstaben zu suchen: Gehe die Indizes i von 0 bis Länge des Strings durch und wenn das Zeichen des Strings an der Stelle i eine öffnende Klammer ist, schreie "huhu!". Dazu mußt Du Dein Werkstattreppenbeispiel nur leicht modifizieren.
@heiner88: Stimmt, zu beschreiben wie man mit solchen Fällen umgeht, gehört zu einer Lösung dazu. Ich würde es mir einfach machen und verschachtelte Klammern als ungültige Eingabe ansehen und beschreiben, dass bei solchen Eingaben das Ergebnis undefiniert ist.
Man könnte natürlich auch explizit darauf prüfen und das entsprechend als Fehler melden.
Von Erlang's ”Pfeilsyntax” für Funktionen inspiriert habe ich meine drei Io-Varianten mal nach CoffeeScript portiert:
[codebox=coffeescript file=Unbenannt.coffee]#!/usr/bin/env coffee
'use strict'
String::hervorhebenB = ->
result = []
openBraceIndex = null
for character, i in @
if openBraceIndex is null
if character == '(' then openBraceIndex = i else result.push character
else
if character == ')'
result.pop() if i - openBraceIndex > 1
openBraceIndex = null
else
result.push character, '_'
result.join ''
Wenn man das ganze nach FreeBASIC portiert sehen die Varianten B und C nicht so viel anders aus, aber es gibt so ein nostalgisches Gefühl, dass man das damals unter DOS in QBasic so hätte lösen können. Bei Variante A sieht man wie lang eine Lösung mit regulären Ausdrücken werden kann, wenn man keine moderne Sprache/Bibliothek verwendet, die das besser unterstützt.
[codebox=freebasic file=Unbenannt.txt]#include once "pcre.bi"
FUNCTION sperrdruck$(text AS STRING)
DIM result AS STRING, i AS INTEGER
result = ""
FOR i = 1 TO Len(text)
result = result + Mid$(text, i, 1)
IF i < Len(text) THEN result = result + "_"
NEXT
sperrdruck$ = result
END FUNCTION
FUNCTION hervorhebenA$(text AS STRING)
CONST cOvectorCount = 6, pattern = "\((.*?)\)"
DIM result AS STRING, re AS PCRE PTR, errorMessage AS ZSTRING PTR, _
errorOffset AS INTEGER, startIndex AS INTEGER, rc AS INTEGER, _
ovector(cOvectorCount - 1) AS INTEGER
re = PCRE_Compile(pattern, 0, @errorMessage, @errorOffset, NULL)
IF re = NULL THEN
PRINT "error compiling pattern: "; *errorMessage; " at "; errorOffset
PRINT pattern
PRINT Space(errorOffset); "^"
END
END IF
IF rc <> PCRE_ERROR_NOMATCH THEN
PRINT "matching error: "; rc
END
END IF
hervorhebenA$ = result + Mid$(text, startIndex + 1, Len(text))
END FUNCTION
FUNCTION hervorhebenB$(text AS STRING)
DIM result AS STRING, openIndex AS INTEGER, i AS INTEGER, ch AS STRING
result = ""
openIndex = -1
FOR i = 1 TO Len(text)
ch = Mid$(text, i, 1)
IF openIndex = -1 THEN
IF ch = "(" THEN openIndex = i ELSE result = result + ch
ELSE
IF ch = ")" THEN
IF i - openIndex > 1 THEN result = Left$(result, Len(result) - 1)
openIndex = -1
ELSE
result = result + ch + "_"
END IF
END IF
NEXT
hervorhebenB$ = result
END FUNCTION
FUNCTION hervorhebenC$(text AS STRING)
DIM startIndex AS INTEGER, openIndex AS INTEGER, closeIndex AS INTEGER, _
result AS STRING
result = ""
startIndex = 1
GOTO get_open_index
DO
result = result + Mid$(text, startIndex, openIndex - startIndex)
closeIndex = InStr(openIndex + 1, text, ")")
IF closeIndex = 0 THEN
startIndex = openIndex + 1
ELSE
result = result + sperrdruck$(Mid$(text, openIndex + 1, _
closeIndex - openIndex - 1))
startIndex = closeIndex + 1
END IF
get_open_index:
openIndex = InStr(startIndex, text, "(")
LOOP UNTIL openIndex = 0
hervorhebenC$ = result + Mid$(text, startIndex)
END FUNCTION
def klammer(str):
k = 0
s = ""
for i, ch in enumerate(str):
if ch == '(':
k += 1
if k > 1:
s += "(_"
elif ch == ')':
if k > 1:
s += ")_"
if k == 1:
s = s[:-1] if i > 0 and s[-1] == "_" else s
k -= 1
if k < 0:
k = 0
else:
s += ch
if k > 0:
s += "_"
return s
s1 = ")Ein (kleines) Beispiel(), (ohne) Kla(mm)er(n). ((aa)). ((aa(bb)cc)). (aa(bb(cc)dd)ee)."
print(s1)
s2 = klammer(s1)
print(s2)