Autor |
Beitrag |
-delphin-
      
Beiträge: 200
|
Verfasst: 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):
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); 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+1] then getauscht := true; tausche(folge[i], folge[i+1]); 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
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
      
Beiträge: 777
(Win98, WinMe) WinXP Prof
D3 Prof, D6 Pers, D2k5 Pers., Turbo C++ Explorer
|
Verfasst: 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- 
      
Beiträge: 200
|
Verfasst: 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
      
Beiträge: 221
Windows XP Home
Delphi 7 PE, Delphi 2005 PE
|
Verfasst: 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:
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
      
Beiträge: 777
(Win98, WinMe) WinXP Prof
D3 Prof, D6 Pers, D2k5 Pers., Turbo C++ Explorer
|
Verfasst: 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
      
Beiträge: 221
Windows XP Home
Delphi 7 PE, Delphi 2005 PE
|
Verfasst: 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:
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 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
      
Beiträge: 849
|
Verfasst: Sa 17.09.05 18:55
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- 
      
Beiträge: 200
|
Verfasst: Sa 17.09.05 23:04
So, habe das jetzt optimiert, aber er sortiert immernoch nicht!
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+1] then begin getauscht := true; tausche(folge[i], folge[i+1]); Edit2.Text:=folge; end; end; until not getauscht; end; end. |
Nur warum 
|
|
ManuelGS
      
Beiträge: 173
Win XP HE, Suse Linux
D6, D7, D2005 Personal
|
Verfasst: 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
      
Beiträge: 777
(Win98, WinMe) WinXP Prof
D3 Prof, D6 Pers, D2k5 Pers., Turbo C++ Explorer
|
Verfasst: 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
      
Beiträge: 221
Windows XP Home
Delphi 7 PE, Delphi 2005 PE
|
Verfasst: 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
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- 
      
Beiträge: 200
|
Verfasst: 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- 
      
Beiträge: 200
|
Verfasst: So 18.09.05 09:31
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; repeat for i:=1 to j do begin getauscht:=false; If j[i]>j[i+1] then 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
      
Beiträge: 221
Windows XP Home
Delphi 7 PE, Delphi 2005 PE
|
Verfasst: 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!
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 SetLength(Folge, Memo1.Lines.Count); for i:=0 to Memo1.Lines.Count-1 do Folge[i]:=Memo1.Lines[i];
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;
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:
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 Help:=TStringList.Create; Help.Sorted:=true;
Help.Text:=Memo1.Text; FreeAndNil(Help); end; |
|
|
-delphin- 
      
Beiträge: 200
|
Verfasst: 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
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: 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- 
      
Beiträge: 200
|
Verfasst: 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.
|
|
|