Autor Beitrag
-delphin-
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 200



BeitragVerfasst: Sa 17.09.05 14:24 
Hallo Forum, ich möchte einen BubbleSort-Algo schreiben, bzw habe ihn auch schon geschrieben. Dabei werden die Zahlen zuerst per Zufallsgenerator ins Memo1 eingeschrieben und bei Klick auf Button2 (Sortieren) zuerst ins Memo2 kopiert und dort sortiert.
Das sieht wiefolgt aus (nur der BubbleSort-Teil):

ausblenden 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:
28:
29:
procedure TForm1.tausche(var a,b,c : string);
//var c : string;
begin
  c:=a;
  a:=b;
  b:=c;
end;

procedure TForm1.Button2Click(Sender: TObject);
var Folge    : string;
    i, j     : integer;
    getauscht: boolean;
begin
  folge := Memo1.Text;
  Memo2.Text := folge;
  j := Memo1.Lines.Count;
  repeat
    getauscht := false;
    j := j-1;
    for i := 1 to j do
    begin
      if folge[i]>folge[i+1then
      getauscht := true;
      tausche(folge[i], folge[i+1]); //<--- Hier der Fehler
      Memo2.Text:=folge;
    end;
  until not getauscht;
end;
end.


In der markierten Zeile besteht der Fehler darin, dass "die tatsächlichen und die formalen Var-Parameter" nicht übereinstimmen, also Folge und i, wie ich das sehe.
Würde gerne dieses Problem beheben,
thx 4 help :D

Edit: Damit keine Verwirrung aufkommt: Selbiger Fehler besteht natürlich auch bei folge[i+1], also sind es zwei Fehler, die sich aber wohl gleichzeitig beheben lassen, nur wie :?:
Amateur
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 777

(Win98, WinMe) WinXP Prof
D3 Prof, D6 Pers, D2k5 Pers., Turbo C++ Explorer
BeitragVerfasst: Sa 17.09.05 15:13 
a,bund c bei der tausche procedure wurden mit var als parameter übergeben. damit will er die globalen variablen a,b und c haben. musst du ma das var da wegmachen dann sollte es gehn.
wenns falsch is verbessert mich aber so hab ich das mit dem var bei parametern verstanden. lass einfach ma das var in der parameterübergabe weg und versuch es dann mal

_________________
"Kein dummes Gerede. Kein Rumrätseln. Denkt an nichts anderes mehr, nur noch an das, was vor euch liegt. Das ist die wahre Herausforderung. Ihr müßt euch vor euch selbst schützen, Leute." (Rennes in "Cube")
Beiträge: >700
-delphin- Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 200



BeitragVerfasst: Sa 17.09.05 18:24 
Okay, jetz kann ichs starten, aber es ist trotzdem ein Fehler im Quellcode, weil er nicht sortiert, bei Klick auf sortieren, überträgt er nur das was im Memo1 ist in Memo2. Woran liegt das? File ist im Anhang, falls es jemand benötigt.
Einloggen, um Attachments anzusehen!
Grishnak
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: Sa 17.09.05 18:32 
Warum übergibst du der Tauschen-Prozedur drei Werte, wenn zwei Werte miteinander vertauscht werden sollen? Ich würde dies so machen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure Tausch(var a, b: string);
var
  c: string;
begin
  c:=a;
  a:=b;
  b:=c;
end;


Du musst a und b als var-Parameter übergeben, da sonst die Änderungen innerhalb der Prozedur nicht nach außen wirken (d.h. wenn du das "var" weglässt, dann werden a und b zwar innerhalb der Prozedur getauscht, aber wenn die Prozedur beendet ist, sind diese Änderungen nichtig, da innerhalb der Prozedur nur mit Kopien von a und b gearbeitet wurde!).

Dein BubbleSort-Algorithmus habe ich mit allerdings noch nicht genau angeschaut! Aber einiges ist mir "auf die Schnelle" aufgefallen:

- Denke daran, dass in StringListen die Zählung mit 0 beginnt (Bei 7 Elementen also von 0 bis 6). Du setzt j aber auf .Count!
- Wenn die for-Schleife zum letzen Mal durchlaufen wird, greifst du auf folge[i+1] (=folge[j+1]) zu, also außerhalb des gültigen Bereiches!
- Wenn die innere if-Bedingung (if folge[i]>...) zutrifft, wird nur getauscht auf true gesetzt! Die anschließende Vertauschung wird immer ausgeführt! Hier musst du evtl. mit begin..end einen Block bilden!

_________________
Mach' etwas idiotensicher und irgendjemand erfindet einen besseren Idioten!
Amateur
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 777

(Win98, WinMe) WinXP Prof
D3 Prof, D6 Pers, D2k5 Pers., Turbo C++ Explorer
BeitragVerfasst: Sa 17.09.05 18:33 
hm dann stimmt was mit deinem algorithmus zum sortieren net. gibt aber genug beispiele für sortieralgorithmen also solltest du mit hilfe der suche und ein paar code beispielen den fehler in deinem code finden.
ich habs net so mit sortiersachen etc...

_________________
"Kein dummes Gerede. Kein Rumrätseln. Denkt an nichts anderes mehr, nur noch an das, was vor euch liegt. Das ist die wahre Herausforderung. Ihr müßt euch vor euch selbst schützen, Leute." (Rennes in "Cube")
Beiträge: >700
Grishnak
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: Sa 17.09.05 18:51 
Noch was aufgefallen:

Nach der Zuweisung "folge := Memo1.Text;" stehen im String 'folge' alle Zeilen des Memo1-Objektes durch #13#10 getrennt. Wenn du dann mittels "folge[i]" auf diesen String zugreifst, dann ist dies nicht der i-te String, sondern das i-te Zeichen (char) innerhalb des Strings 'folge'! So kann das also gar nicht funktionieren!

Versuch mal die (kopierten Strings) im Memo2-Objekt mittels dessen Property 'Lines' anzusprechen bzw. zu vertauschen!

Hier noch ein Bubblesort-Algorithmus, der funktioniert:

ausblenden 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:
28:
29:
30:
type
  TStringArray = array of string;

[...]

procedure Tausche(var a, b: string);
var
  c: string;
begin
  c:=a;
  a:=b;
  b:=c;
end;

procedure Bubblesort(var Feld: TStringArray);
var
  i: integer;
  nichtvertauscht: boolean;
begin
  repeat
    nichtvertauscht:=true;
    for i:=0 to Length(Feld)-2 do // Feld hat x Elemente, also 0 bis x-1, der Algorithmus geht bis zum vorletzen Element (x-1)-1 also x-2!
      if Feld[i] > Feld[i+1]
        then
          begin
            Tausche(Feld[i], Feld[i+1]);
            nichtvertauscht:=false;
          end;
  until nichtvertauscht;
end;

_________________
Mach' etwas idiotensicher und irgendjemand erfindet einen besseren Idioten!


Zuletzt bearbeitet von Grishnak am Sa 17.09.05 18:57, insgesamt 1-mal bearbeitet
Sprint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: Sa 17.09.05 18:55 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure TForm1.Button1Click(Sender: TObject);
var
  I, J: Integer;
begin

  with Memo1.Lines do
  begin
    BeginUpdate;
    for I := 0 to Count - 1 do
      for J := 0 to Count - 1 do
        if CompareStr(Strings[I], Strings[J]) < 0 then
          Exchange(I, J);
    EndUpdate;
  end;

end;


Würde das nicht schon so reichen?

_________________
Ciao, Sprint.
-delphin- Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 200



BeitragVerfasst: Sa 17.09.05 23:04 
So, habe das jetzt optimiert, aber er sortiert immernoch nicht!

ausblenden volle Höhe 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:
28:
29:
30:
31:
32:
procedure TForm1.tausche(a,b : string);
var c : string;
begin
  c:=a;
  a:=b;
  b:=c;
end;

procedure TForm1.Button2Click(Sender: TObject);
var Folge    : string;
    i, j       : integer;
    getauscht: boolean;
begin
  folge := Edit1.Text;
  Edit2.Text := folge;
  folge := Edit1.Text;
  j := Length(Edit1.Text);
  repeat
    getauscht := false;
    j := j-1;
    for i := 1 to j do
    begin
      if folge[i]>folge[i+1then
      begin
        getauscht := true;
        tausche(folge[i], folge[i+1]);
        Edit2.Text:=folge;
      end;
    end;
  until not getauscht;
end;
end.


Nur warum :?:
ManuelGS
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 173

Win XP HE, Suse Linux
D6, D7, D2005 Personal
BeitragVerfasst: Sa 17.09.05 23:48 
Also bei deiner Tausche-Prozedur muss mal auf jeden Fall noch ein Var vor die Variablen, damit die Änderungen auch aus der Prozdur RAUS gehen!

_________________
"Leben ist gänzlich Bühne und Spiel; so lerne denn spielen
und entsage dem Ernst - oder erdulde das Leid." - Palladas von Alexandria
Amateur
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 777

(Win98, WinMe) WinXP Prof
D3 Prof, D6 Pers, D2k5 Pers., Turbo C++ Explorer
BeitragVerfasst: Sa 17.09.05 23:52 
wenn er aber das var lässt müsste er dann net das a und b später auswerten und halt in die liste mit den wörtern erst a und dann b anstatt folge[i] setzen?

_________________
"Kein dummes Gerede. Kein Rumrätseln. Denkt an nichts anderes mehr, nur noch an das, was vor euch liegt. Das ist die wahre Herausforderung. Ihr müßt euch vor euch selbst schützen, Leute." (Rennes in "Cube")
Beiträge: >700
Grishnak
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: So 18.09.05 00:43 
@Amateuer: Nein, müsste er nicht! Das "var" bedeutet nur, dass nicht Kopien der Variablen an die Prozedur übergeben werden (denn wenn man die ändert, ändern sich die Originale natürlich nicht mit!), sondern das die Variabeln direkt übergeben werden (und dann natürlich auch von der Prozedur verändert werden können - was ja hier erwünscht ist!). Diese Art der Übergabe ("var") nennt man 'by Reference', während man die Übergabe ohne "var" 'by Value' nennt.

@Delphin: Das kann nicht funktionieren, weil "folge[i]" ein einzelnes Zeichen des Strings "folge" ist (der wiederum aus allen Zeilen des TMemo besteht) und nicht die einzelnen Strings des Memo! Wie soll ich es anders erklären... ein Beispiel:

Angenommen in TMemo1 steht
ausblenden Quelltext
1:
2:
3:
4:
Birne
Apfel
Zitrone
Orange


Dann ist "TMemo1.Text" gleich 'Birne#13#10Apfel#13#10Zitrone#13#10Orange#13#10' (wobei #13#10 für zwei Zeichen mit den Ascii-Codes 13 bzw. 10 stehen (Wagenrücklauf und Zeilenvorschub). Dieser String wird nun dem String "folge" zugewiesen.

Daraus folgt, dass "folge[2]" weder 'Zitrone' noch 'Apfel' ist ('Apfel' hätte eh' den Index 1), sondern schlicht und ergreifend nur 'i' (das 'i' in 'Birne'!). Dein Bubblesort sortiert also höchstens einzelne Zeichen, aber keine ganzen Strings!

_________________
Mach' etwas idiotensicher und irgendjemand erfindet einen besseren Idioten!
-delphin- Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 200



BeitragVerfasst: So 18.09.05 09:21 
dann seht euch mal den thread ganz oben an, da hatte ich das problem, dass er einen fehler in der zeile folge[i]>folge[i+1] macht, weil ich bei der tausche-prozedur ein var übergeben habe.
desweiteren muss ich dann eben einen anderen befehl nehmen statt .Text, aber .Lines.Count+1 bringt mir auch nicht das gewünschte ergebnis oder?
-delphin- Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 200



BeitragVerfasst: So 18.09.05 09:31 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
  Inhalt := Memo1.Text;
  Memo2.Text := Inhalt;
  j := Memo1.Lines.Count; //<- Hier IntToStr(Memo1.Lines.Count);
  repeat
    for i:=1 to j do //<- und hier wieder StrToInt(j);
    begin
      getauscht:=false;
      If j[i]>j[i+1then //<--
      begin
        tausche(j[i], j[i+1]); //<--
        getauscht:=true;
      end;
    end;
  until not getauscht;
end;
end.


So hab ichs jetzt mal gemacht, geht aber nicht, weil er in den markierten Zeilen bei j[i] einen Array haben möchte, warum auch immer, wollte er bisher nie. j ist integer, vorher war folge immer string, vll gehts deshalb nicht.

Edit: Jetz ist j string. Mache ich es mit IntToStr und bei der Schleife wieder zurück (markiert), dann hängt er sich auf bzw. rechnet ewig, immerhin ein Fortschritt.
Grishnak
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: So 18.09.05 11:23 
Dein BubbleSort würde - wenn es funktionieren würde! - nur einen einzigen String sortieren und zwar die darin enthaltenen Buchstaben! D.h. es würde aus 'Apfel' dann 'Aeflp' machen! Um mehrere Strings zu sortieren, brauchts du auch mehrere String-Variablen oder noch besser ein String-Array!

ausblenden volle Höhe 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:
28:
29:
30:
31:
32:
33:
34:
35:
36:
procedure Tausche(var a, b: string);
var
  c: string;
begin
  c:=a;
  a:=b;
  b:=c;
end;

procedure TForm1.Button1Click(Sender: TObject);
var Folge: array of string;
    i: integer;
    nichtvertauscht: boolean;
begin
  (* alle Zeilen des Memo1 in das Array kopieren *)
  SetLength(Folge, Memo1.Lines.Count);
  for i:=0 to Memo1.Lines.Count-1 do
    Folge[i]:=Memo1.Lines[i];

  (* Bubblesort *)
  repeat
    nichtvertauscht:=true;
    for i:=0 to Length(Folge)-2 do
      if Folge[i] > Folge[i+1]
        then
          begin
            Tausche(Folge[i], Folge[i+1]);
            nichtvertauscht:=false;
          end;
  until nichtvertauscht;

  (* sortiertes Array in Memo2 kopieren *)
  Memo2.Clear;
  for i:=0 to Length(Folge)-1 do
    Memo2.Lines.Add(Folge[i]);
end;


Man könnte natürlich auch per "Memo2.Text:=Memo1.Text" erst die unsortierten Zeilen von Memo1 nach Memo2 kopieren und dann Memo2 direkt sortieren!

Und wenn es gar nicht wichtig ist, welcher Sortier-Algorithmus erforderlich ist, dann kann man auch den Umweg über eine sortierte TStringList machen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure TForm1.Button1Click(Sender: TObject);
var
  Help: TStringList;
begin
  (* Stringliste erzeugen *)
  Help:=TStringList.Create;
  Help.Sorted:=true;

  (* alle Zeilen von Memo1 hineinkopieren - dabei werden diese sortiert *)
  Help.Text:=Memo1.Text;
  (* sortierte Zeilen in Memo2 hineinkopieren
  Memo2.Text:=Help.Text;

  (* Hilfsliste löschen *)

  FreeAndNil(Help);
end;
-delphin- Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 200



BeitragVerfasst: So 18.09.05 11:45 
es ist wichtig, ich muss für info ein referat machen und zwar über BubbleSort und ich bemühe mich den zu verstehen bzw. ein prog zu machen, was funktioniert ;)
Edit: Wunderbar, das geht jetzt erstmal, vielen Dank! Ein Problem, was logischerweise noch existiert, sind Zahlen, die zweistellig sind, d.h. zum Beispiel die Folge 3-2-9-5-10 sortiert er 10-2-3-5-9, aufgrund der 1.
Das liegt wohl daran, dass es ein String-Array ist, oder?
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: So 18.09.05 12:05 
Ja! Alphabetisch gesehen liegt die Zeichenkette '10' zwischen '1' und '2'. Wenn Du numerisch sortieren willst, musst Du die Strings in Zahlen umwandeln, z.B. mit iNumber := IntToStr (sString)
-delphin- Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 200



BeitragVerfasst: So 18.09.05 12:50 
Jetz habe ich halt nur ein Memo in dem abwechselnd oder sogar gleichzeitig Strings und Integers stehen können.