Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Schleife vorzeitig beenden
wieczo - Do 26.09.02 21:42
Titel: Schleife vorzeitig beenden
Hallo alle zusammen,
hab mal wieder ein Problem. Ich überprüfe einen String auf eine Klammer,
sobald er eine findet, soll er wieder aus der Schleife raus. Wie kriege ich das denn hin? Mein Codeausschnitt:
Quelltext
1: 2: 3: 4: 5:
| for i := length(s) downto 1 do begin if s[i] = ')' then delete(s, i, 1); hier will ich aus der schleife raus end; |
Vielen Dank im Voraus Thomas
Tino - Do 26.09.02 21:46
Break heißt das Zauberwort!
Delphi-Hilfe hat folgendes geschrieben: |
Die Prozedur Break verläßt eine for-, while- oder repeat-Schleife. |
Gruß
wieczo - Do 26.09.02 22:14
Vielen Dank dafür Tino,
doch schon plagt mich das nächste Problem. Ein Stackoverflow (:()! Ich soll für die Schule eine Klammernfolge auf Korrektheit prüfen. Programmiert hab ich folgendes:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| procedure TForm1.pruefen(var s : string; var ok : boolean); var i : integer; begin memo1.lines.Add('Wird geprüft: ' + s); if length(s) = 1 then ok := false else begin for i := 1 to length(s) do begin if s[i] = '(' then delete(s, i, 1); break end; for i := length(s) downto 1 do begin if s[i] = ')' then delete(s, i, 1); break end; if length(s) > 0 then pruefen(s, ok) else ok := true; end end; |
Er klappt bei Folgen wie
'((()))', doch wenn ich
'()()', was auch korrekt ist, eintippe, gibt es einen Stack overflow. Sieht jemand den Fehler?
Danke schön im Voraus Thomas
Tino - Do 26.09.02 22:24
Also ich würde das so machen:
Als erstes habe ich eine Integer Variable (Wert am Anfang 0)
Dann gehe ich in einer Schleife den String Zeichen für Zeichen durch und überprüfe:
- Wenn das Zeichen ein ( ist dann die Variable um eins hoch setzen
- Wenn das Zeichen ein ) ist dann die Variable um eins runter setzen
Am Ender der Schleife musst Du nur noch die Variable überprüfen. Ist diese ungleich 0 ist ein Fehler vorhanden.
Sollte doch funktionieren oder hab ich eventl. etwas vergessen :? :roll: :think:
Gruß
TINO
wieczo - Do 26.09.02 22:27
So habe ich das auch schon gelöst, aber ich soll das auch rekursiv machen.
Trotzdem Dankeschön
opfer.der.genauigkeit - Fr 27.09.02 10:42
Ich sehe den Fehler zwar nich und um ehrlich zu sein blick ich da auf anhieb nich durch.
Aber versuch doch mit Breakpoints zu arbeiten und dir die Werte von s bzw. i anzeigen zu lassen.
Dann wird dir auch klar, warum das nicht funktionieren kann.
Is nur ne Idee von nem Noob. :wink:
wieczo - Sa 28.09.02 04:09
Ich laß mir die neue Klammerfolge im Memo immer ausgeben, wenn die Prozedur wieder aufgerufen wird und wenn ich ()() eingebe gibt er die ganze Zeit bis zum stack overflow )( aus. Der ruf sich immer selbst auf.
Die breakpoints funktionieren irgendwie net.
Danke Thomas
LCS - Sa 28.09.02 11:08
Hi
den Stack Overflow bekommst du bei deinem Code aus zwei Gründen:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| procedure TForm1.pruefen(var s : string; var ok : boolean); var i : integer; begin memo1.lines.Add('Wird geprüft: ' + s); if length(s) = 1 then ok := false else begin for i := 1 to length(s) do begin if s[i] = '(' then delete(s, i, 1); break //Dieses Break wird IMMER ausgeführt. Sollte aber nur wenn s[i] = '(' end; for i := length(s) downto 1 do begin if s[i] = ')' then delete(s, i, 1); break //Genau wie oben end; if length(s) > 0 then //Was passiert wenn alle Klammern raus sind und trotzdem noch //Zeichen da sind (a)(b). Dann läuft das endlos pruefen(s, ok) else ok := true; end end; |
Da wirst du dir also wohl oder übel noch mal nen Kopf machen müssen. :think:
Tino hat folgendes geschrieben: |
Wenn das Zeichen ein ( ist dann die Variable um eins hoch setzen
Wenn das Zeichen ein ) ist dann die Variable um eins runter setzen
Am Ender der Schleife musst Du nur noch die Variable überprüfen. Ist diese ungleich 0 ist ein Fehler vorhanden.
Sollte doch funktionieren oder hab ich eventl. etwas vergessen
|
Was passiert hier:
)(a)(b)( :mrgreen:
Gruss Lothar
Tino - Sa 28.09.02 12:44
LCS hat folgendes geschrieben: |
Was passiert hier: )(a)(b)( |
Stimmt. Das heißt man müsste bei jeden Durchlauf prüfen ob die Integer-Variable noch einen gültigen Wert hat (>= 0).
Gruß
TINO
Anonymous - Sa 28.09.02 16:54
Ich hab auf die Schnelle ein Beispiel geschrieben wie ich das zählen würde. Das Beispiel ist zwar ausbaufähig, aber für ein drei Minuten Code ok:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| var i, Klammern: Integer; Text: String; begin Text := '(((a + b)))-(c / d)+(a)*(d)/(g)*(((2 + 1)))'; Klammern := 0;
for i := 1 to Length(Text) do begin if Text[i] = '(' then Inc(Klammern); if Text[i] = ')' then Dec(Klammern); if Klammern < 0 then ShowMessage( 'Falsche Klammerfolge' ); end;
if Klammern = 0 then ShowMessage( 'Anzahl korrekt' ) else ShowMessage( 'Anzahl der Klammern ist falsch: ' + IntToStr(Klammern) ); end; |
Guck ob du da etwas von gebrauchen kannst.
Anonymous - Sa 28.09.02 16:57
Ich sehe gerade, daß hier eine "Falsche Klammerfolge" angezeigrt werden kann, dann aber die Meldung "Anzahl korrekt". Wiederspricht sich zwar nicht, aber man könnte es mißverstehen.
wieczo - So 29.09.02 15:24
Vielen Dank an euch alle, besonders LCS. Tja wenn man ein bisschen blind ist :oops: , freut man sich über die, die besser sehen. Also Danke schön.
Ich probiere mich jetzt an dieser Folge )()(. Falls jemand eine Idee, ich freue mich über jeden Vorschlag.
Tschö Thomas
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!