Autor Beitrag
wieczo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 48


D6 Pers, TP 7.0
BeitragVerfasst: Do 26.09.02 21:42 
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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Veteran
Beiträge: 9839
Erhaltene Danke: 45

Windows 8.1
Delphi XE4
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 48


D6 Pers, TP 7.0
BeitragVerfasst: 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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Veteran
Beiträge: 9839
Erhaltene Danke: 45

Windows 8.1
Delphi XE4
BeitragVerfasst: 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:
  1. Wenn das Zeichen ein ( ist dann die Variable um eins hoch setzen
  2. 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 48


D6 Pers, TP 7.0
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 754
Erhaltene Danke: 1



BeitragVerfasst: 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:

_________________
Stellen Sie sich bitte Zirkusmusik vor.
wieczo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 48


D6 Pers, TP 7.0
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1305
Erhaltene Danke: 1

WIN 7, WIN 8
Delphi XE5, Delphi XE, Delphi 2007
BeitragVerfasst: Sa 28.09.02 11:08 
Hi
den Stack Overflow bekommst du bei deinem Code aus zwei Gründen:
ausblenden 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

_________________
Der BH ist für die Brust, der Plan ist für'n Ar...
Tino
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Veteran
Beiträge: 9839
Erhaltene Danke: 45

Windows 8.1
Delphi XE4
BeitragVerfasst: 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
Popov
Gast
Erhaltene Danke: 1



BeitragVerfasst: 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:

ausblenden 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.
Popov
Gast
Erhaltene Danke: 1



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 48


D6 Pers, TP 7.0
BeitragVerfasst: 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