Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - schleifenproblem ?


noo.bee - Fr 04.06.10 19:13
Titel: schleifenproblem ?
... oder ein denkfehler ??? kurze erklärung:
ich habe die variablen a, b, c und d. diese sollen einzeln von hinten (also bei d beginnend) inkrementiert werden. also zuerst inc(d) bis es max 19 wird. dann wird c um 1 erhöht und d beginnt wieder bis 19 zu laufen. dann wird wieder c um eins erhöht und d beginnt wieder bei 1 zu laufen usw...
rauskommen soll zum ende sowas:

a b c d
1 2 3 4
1 2 3 5
1 2 3 6
...
1 2 4 5
1 2 4 6
1 2 4 7
...
10 11 12 13
10 11 12 14
10 11 12 15... eben solange, bis a 19 ist

mein gedanke war dieser:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure TForm2.Button1Click(Sender: TObject);
begin

a := 1; b := 1; c := 1; d := 1;
Durchlauf := 0;

while a<20 do                // schleife durchführen, bis a kleiner 20
begin
inc(d);
  if d>19 then               // wenn "d" größer 49 dann beginne "c" zu inkrementieren
  inc(c); d := 1;            //
    if c>19 then             // wenn "c" größer 49 dann beginne "b" zu inkrementieren
    inc(b); c := 1;          //
        if b>19 then         // wenn "b" größer 49 dann beginne "a" zu inkrementieren
        inc(a); b := 1;      //
          if a>19 then       // wenn "a" größer 49 dann tue nichts mehr
          ;                  //
          inc(Durchlauf);    // Durchlauf inkrementieren
          end;
end;


jaenicke - Fr 04.06.10 19:22

Rück richtig ein, dann siehst du den Fehler auch schon...

Delphi-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:
26:
27:
procedure TForm2.Button1Click(Sender: TObject);
begin

a := 1;
b := 1;
c := 1;
d := 1;
Durchlauf := 0;

while a < 20 do                // schleife durchführen, bis a kleiner 20
begin
  Inc(d);
  if d > 19 then               // wenn "d" größer 49 dann beginne "c" zu inkrementieren
    inc(c);
  d := 1;            //
  if c > 19 then             // wenn "c" größer 49 dann beginne "b" zu inkrementieren
    Inc(b);
  c := 1;          //
  if b > 19 then         // wenn "b" größer 49 dann beginne "a" zu inkrementieren
    Inc(a);
  b := 1;      //
  if a > 19 then       // wenn "a" größer 49 dann tue nichts mehr
    ;                  //
  Inc(Durchlauf);    // Durchlauf inkrementieren
end;

end;
Du setzt die Werte doch alle bis auf a bei jedem Durchlauf wieder auf 1. Also hast du eine Endlosschleife.

Suchst du vielleicht das? ;-)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
for a := 1 to 19 do
  for b := 1 to 19 do
    for c := 1 to 19 do
      for d := 1 to 19 do
      begin
        // tu was
      end;


Bergmann89 - Fr 04.06.10 19:24

Hey,

du hast die Begin-End-Blocke der if-Abfragen vergessen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure TForm2.Button1Click(Sender: TObject);
begin

a := 1; b := 1; c := 1; d := 1;
Durchlauf := 0;

while a<20 do begin          // schleife durchführen, SOLANGE a kleiner 20
  inc(d);
  if d > 19 then begin             
    inc(c); 
    d := 1;           
    if c > 19 then begin
      inc(b); 
      c := 1;          
        if b > 19 then begin
          inc(a); 
          b := 1;   
        end;   
      end;
    end;
  end;
end;

€: zu langsam^^


noo.bee - Fr 04.06.10 19:44

:oops:
Zitat:
Du setzt die Werte doch alle bis auf a bei jedem Durchlauf wieder auf 1.
war eigentlich so geplant, weil

wenn d = 19 ist wird d wieder zu 1 und c zu 2 -> dann
wenn d = 19 ist wird d wieder zu 1 und c zu 3 -> deshalb soll ja b,c,d nach dem durchlauf bis 19 jeweils wieder 1 werden und von vorne beginnen

oder hast du's falsch verstanden ?


Bergmann89 - Fr 04.06.10 20:10

Hey,

du setzt aber die Werte jedesmal wenn du die While-Schleife durchläufst auf 1, nicht nur wenn der vorherige Wert größer 19 ist. Warum machst du's nich mit den for-Schleifen?

MfG Bergmann


noo.bee - Fr 04.06.10 21:09

ok, ich teste mal die for schleifen.

wie kann ich mir als "beweis" die variablen a,b,c,d mit nem memo anschauen ?
also ich müßte ja dann darin folgendes stehen haben:

1 2 3 4
1 2 3 5
1 2 3 6
...


Stundenplan - Fr 04.06.10 21:12

Mit Memo1.Lines.Add('Neue Zeile'); fügst du eine neue Zeile in ein Memo ein.


noo.bee - Fr 04.06.10 21:26

sorry, falsch ausgedrückt. also es sollen natürlich alle variablen zu sehen sein.

also
1 2 3 4
1 2 3 5
1 2 3 6 ...

mit Memo1.Lines.Add(inttostr(a)); kann ich ja nur einen wert wiedergeben. und


Delphi-Quelltext
1:
2:
3:
4:
Memo1.Lines.Add(inttostr(a));
Memo1.Lines.Add(inttostr(b));
Memo1.Lines.Add(inttostr(c));
Memo1.Lines.Add(inttostr(d));
hab ich kein brauchbares ergebnis


Stundenplan - Fr 04.06.10 21:35

Und Memo1.Lines.Add(inttostr(a) + ' ' + inttostr(b) + ' ' + inttostr(c) + ' ' + inttostr(d)); ? :wink:


noo.bee - Fr 04.06.10 22:01

ok, funzt, ABER ich hab genau das, waas ich oben nicht wollte.
so sieht das ergebnis aus

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:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
1 1 1 1
1 1 1 2
1 1 1 3
1 1 1 4
1 1 1 5
1 1 1 6
1 1 1 7
1 1 1 8
1 1 1 9
1 1 1 10
1 1 1 11
1 1 1 12
1 1 1 13
1 1 1 14
1 1 1 15 --> ab hier sollte es aber auf 1 1 2 3 springen und dann auf 1 1 2 4, 1 1 2 5, 1 1 2 6 ...
1 1 1 16
1 1 2 16
1 1 3 16
1 1 4 16
1 1 5 16
1 1 6 16
1 1 7 16
1 1 8 16
1 1 9 16
1 1 10 16
1 1 11 16
1 1 12 16
1 1 13 16
1 1 14 16
1 1 15 16
1 1 16 16
1 2 16 16 --> ab hier sollte es aber auf 1 2 3 4 springen und dann auf 1 2 3 4, 1 2 3 5, 1 2 3 6 ...
1 3 16 16
1 4 16 16
1 5 16 16
1 6 16 16
1 7 16 16
1 8 16 16
1 9 16 16
1 10 16 16
1 11 16 16
1 12 16 16
1 13 16 16
1 14 16 16
1 15 16 16
1 16 16 16
2 16 16 16
3 16 16 16
4 16 16 16
5 16 16 16
6 16 16 16
7 16 16 16
8 16 16 16
9 16 16 16
10 16 16 16
11 16 16 16
12 16 16 16
13 16 16 16
14 16 16 16
15 16 16 16
16 16 16 16


also mal anders ausgedrückt: ich brauche der reihe nach alle möglichkeiten von 1 bis 15 von unten nach oben aufzeigend...


Stundenplan - Fr 04.06.10 22:21

Welchen Code benutzt du denn jetzt? Die for-Schleifen funktionieren einwandfrei!
Und Bergmanns Code läuft auch!
Du vergisst, die Variablen nach jedem Inkrementieren wieder auf 1 zu setzen.


bole - Fr 04.06.10 22:45

user profile iconStundenplan hat geschrieben
Zitat:
Du vergisst, die Variablen nach jedem Inkrementieren wieder auf 1 zu setzen.


Bei for Schleifen muss man sich nicht um das zurücksetzten kümmern, das ist im for Befehl enthalten. Da die inneren Schleife immer wieder neu initialisiert wird geht das automatisch...

Gruss

Bole

PS: Wenn Du for d := 15 downto 1 do verwendest gehts auch rückwärts!


Stundenplan - Fr 04.06.10 22:52

@bole: Ich meine, in dem Code, den er jetzt verwendet, hat er das Zurücksetzen vergessen! :wink:
Das mit den for-Schleifen ist mir schon klar^^


bole - Fr 04.06.10 22:58

@Stundenplan Sorry wollte Dich nicht Beleidigen.

Mir ist nicht wirklich klar was user profile iconnoo.bee will. In der ursprünglichen Frage ist es 19, dann will er aber plötzlich die Stufe schon bei 15 wechseln und seine Beispiele in der Auflistung und die untenstehende andere Formulierung sind meines Erachtens auch nicht wirklich das selbe...

Gruss
Bole


noo.bee - Fr 04.06.10 23:02

ja 15 oder 19 oder25 is egal ;) die zahlenm sind erstmal wurst. das grundprinzip soll stimmen.
und das ist dieses:

1 2 3 4
1 2 3 5
1 2 3 6
...
7 8 9 10
7 8 9 11
7 8 9 12

momentan probier ich den code


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure TForm2.Button1Click(Sender: TObject);
begin

a := 1; b := 1; c := 1; d := 1;
Durchlauf := 0;

  for d := 1 to 15 do
  Memo1.Lines.Add(inttostr(a) + ' ' + inttostr(b) + ' ' + inttostr(c) + ' ' + inttostr(d));
  d := 1;
    for c := 1 to 15 do
    Memo1.Lines.Add(inttostr(a) + ' ' + inttostr(b) + ' ' + inttostr(c) + ' ' + inttostr(d));
    c := 1;
      for b := 1 to 15 do
      Memo1.Lines.Add(inttostr(a) + ' ' + inttostr(b) + ' ' + inttostr(c) + ' ' + inttostr(d));
      b := 1;
        for a := 1 to 15 do
        Memo1.Lines.Add(inttostr(a) + ' ' + inttostr(b) + ' ' + inttostr(c) + ' ' + inttostr(d));

// edit9.Text := inttostr(Durchlauf);

end;


aber mir will iwie nicht die richtige logische reihenfolge in den kopf :?: weil das ergebnis hier auch falsch ist


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:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
1 1 1 1
1 1 1 2
1 1 1 3
1 1 1 4
1 1 1 5
1 1 1 6
1 1 1 7
1 1 1 8
1 1 1 9
1 1 1 10
1 1 1 11
1 1 1 12
1 1 1 13
1 1 1 14
1 1 1 15
1 1 1 1
1 1 2 1
1 1 3 1
1 1 4 1
1 1 5 1
1 1 6 1
1 1 7 1
1 1 8 1
1 1 9 1
1 1 10 1
1 1 11 1
1 1 12 1
1 1 13 1
1 1 14 1
1 1 15 1
1 1 1 1
1 2 1 1
1 3 1 1
1 4 1 1
1 5 1 1
1 6 1 1
1 7 1 1
1 8 1 1
1 9 1 1
1 10 1 1
1 11 1 1
1 12 1 1
1 13 1 1
1 14 1 1
1 15 1 1
1 1 1 1
2 1 1 1
3 1 1 1
4 1 1 1
5 1 1 1
6 1 1 1
7 1 1 1
8 1 1 1
9 1 1 1
10 1 1 1
11 1 1 1
12 1 1 1
13 1 1 1
14 1 1 1
15 1 1 1


Stundenplan - Fr 04.06.10 23:13

Erstmal: die for-Schleifen sind falschrum, erst a, dann b, usw. :wink: Du vergisst das begin-end, was aber hier nicht nötig wär.
Außerdem du musst nicht in jeder for-Schleife eine Zeile hinzufügen, genausowenig die Variablen auf 1 zurücksetzen, das macht die for-Schleife schon selber! :wink: So sollte das letztlich aussehen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure TForm2.Button1Click(Sender: TObject);
begin
for a := 1 to 19 do  
  for b := 1 to 19 do
    for c := 1 to 19 do
      for d := 1 to 19 do       
        Memo1.Lines.Add(inttostr(a) + ' ' + inttostr(b) + ' ' + inttostr(c) + ' ' + inttostr(d)); 
end;

Grüße,
Stundenplan.


noo.bee - Fr 04.06.10 23:27

ok, danke schonmal bis hierher und sorry wegen der missverständnisse ;)

der code funzt, ABER

1 1 2 17
1 1 2 18
1 1 2 19
1 1 3 1 --> hier ist ein neuer fehler. die reihe soll nicht bei 1 1 3 1 losgehen, sondern bei 1 1 3 4, 1 1 3 5, 1 1 3 6, 1 1 3 7
1 1 3 2
1 1 3 3
...
1 1 3 17
1 1 3 18
1 1 3 19
1 1 4 1 --> hier ist ein neuer fehler. die reihe soll nicht bei 1 1 4 1 losgehen, sondern bei 1 1 4 5, 1 1 4 6, 1 1 4 7, 1 1 4 8
1 1 4 2
1 1 4 3
...
1 1 4 18
1 1 4 19
1 1 5 6 <-- so soll es weitergehen. die letzte zahl(also "d") soll immer um 1 inkrementiert werden beim neuen durchlauf
1 1 5 7
1 1 5 8


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
die endlösung soll so aussehen bei for a := 1 to 07

1 2 3 4
1 2 3 5
1 2 3 6
1 2 3 7
1 2 4 5
1 2 4 6
1 2 4 7
1 2 5 6
1 2 5 7
1 2 6 7
1 3 4 5
1 3 4 6
1 3 4 7
1 3 5 6
1 3 5 7
1 3 6 7
1 4 5 6
1 4 5 7

somit kommt keine 4er kombi doppelt vor


Stundenplan - Fr 04.06.10 23:35

Dann nimmste deinen letzten Code, packst begin-end rein, tust die Memoanzeige nur in die d-for-Schleife, drehst die Reihenfolge der Variablen um, und setzt die Variable nicht auf 1, sondern auf die nächste Variable +1. :wink: (ungetestet)


Bergmann89 - Fr 04.06.10 23:53

Ähm so?!

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm1.Button1Click(Sender: TObject);
var a, b, c, d: Integer;
const MAX = 7;
begin
  for a := 1 to MAX do
    for b := a+1 to MAX do
      for c := b+1 to MAX do
        for d := c+1 to MAX do
          Memo1.Lines.Add(
            IntToStr(a)+' '+
            IntToStr(b)+' '+
            IntToStr(c)+' '+
            IntToStr(d))
end;


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:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
1 2 3 4
1 2 3 5
1 2 3 6
1 2 3 7
1 2 4 5
1 2 4 6
1 2 4 7
1 2 5 6
1 2 5 7
1 2 6 7
1 3 4 5
1 3 4 6
1 3 4 7
1 3 5 6
1 3 5 7
1 3 6 7
1 4 5 6
1 4 5 7
1 4 6 7
1 5 6 7
2 3 4 5
2 3 4 6
2 3 4 7
2 3 5 6
2 3 5 7
2 3 6 7
2 4 5 6
2 4 5 7
2 4 6 7
2 5 6 7
3 4 5 6
3 4 5 7
3 4 6 7
3 5 6 7
4 5 6 7


MfG Bergmann


noo.bee - Fr 04.06.10 23:56

hier hab ichs. so sollte es sein:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
for a := 1 to 09 do
  for b := a + 1 to 09 do
    for c := b + 1 to 09 do
      for d := c + 1 to 09 do
        Memo1.Lines.Add(inttostr(a) + ' ' + inttostr(b) + ' ' + inttostr(c) + ' ' + inttostr(d));
        edit9.Text := inttostr(Durchlauf);
        end;


€: boah neee, jetzt warst schneller ;) aber genau so sollte es aussehen. danke dir/euch für die stundelange hüüülfe :D mega genial von dir/euch ;)


Bergmann89 - Sa 05.06.10 00:08

Kein Ding, aber du hast schon wieder das begin vergessen! Da musst du unbedingt aufpassen, sonst bekommst du auch in Zukunft ganz komische Fehler ;)