Autor |
Beitrag |
Stinger47
      
Beiträge: 102
|
Verfasst: Do 29.11.07 19:10
hi,
wir beschäftigen uns in der schule im moment mit sortierverfahren.
im moment bin ich bei merge-sort allerdings ist dies ein anderer thread.
habe versucht mal einige andere sortierverfahren zu wiederholen und so langsam bin ich am verzweifeln, denn mittlerweile scheine ich schon beim bubble-sort zu scheitern.
habe eine listbox, in die ich items einfüge (zahlen), allerdings sagt er mir, wenn ich den sortier-knopf drücke, dass das listenindex überschritten ist.
hier mal der code:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| procedure TForm1.Button21Click(Sender: TObject); var HILFE : String; begin
for i := 0 to Listbox1.Items.Count - 1 do begin for j := 0 to Listbox1.Items.Count - 1 do begin if Listbox1.Items[j] <= Listbox1.Items[j+1] then begin Hilfe := Listbox1.Items[j]; Listbox1.Items[j] := Listbox1.Items.Strings[j+1]; Listbox1.Items[j+1] := Hilfe; end; end; end;
end; |
der fehler tritt in zeile 11 auf..
danke schon einmal für antworten weiß nicht mehr weiter... 
|
|
Gausi
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Do 29.11.07 19:15
Die innere Schleife darf nur bis Count - 2 laufen, da nur die Elemente 0 bis Count -1 existieren und du auf das j+1-te Element zugreifst 
_________________ We are, we were and will not be.
|
|
jackle32
      
Beiträge: 183
Erhaltene Danke: 7
Win7
Delphi XE5 Starter, RAD Studio XE7 Pro
|
Verfasst: Do 29.11.07 19:18
Hallo,
deine Items aus der Listbox sind vom Typ String.
Man kann aber zwei Strings nicht direkt auf <= überprüfen. Du musst die Strings vorher in Zahlen umwandeln (also mit IntToStr oder mit Float ToStr).
Gruß Jack
Okay geht doch Sorry mein Fehler 
_________________ Es gibt keine dummen Fragen, nur dumme Antworten.
Zuletzt bearbeitet von jackle32 am Do 29.11.07 19:26, insgesamt 1-mal bearbeitet
|
|
Stinger47 
      
Beiträge: 102
|
Verfasst: Do 29.11.07 19:20
hmmm dann sortiert er aber nicht richtig....
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| for i:=0 to stringgrid1.RowCount-1 do begin for j:=0 to stringgrid1.RowCount-1 do begin if stringgrid1.cells[0,j]<=stringgrid1.Cells[0,j+1] then begin Hilfe:= stringgrid1.Cells[0,j]; stringgrid1.cells[0,j]:=stringgrid1.Cells[0,j+1]; stringgrid1.cells[0,j+1]:=Hilfe; end; end; end; |
so funktionierts aber...
EDIT: hier hatten wir das ganze nur einmal mit einem stringgrid durchgeführt und da vergleichen wir a) auch strings miteinander b) geht die zweite schleife hier auch nur bis -1 und es sortiert richtig ohne fehlermeldung...
|
|
Stinger47 
      
Beiträge: 102
|
Verfasst: Do 29.11.07 19:31
@jackle32 kein ding kann ja mal passieren aber war auch kurz verunsichert ob du nicht recht hättest...
bleibt aber immer noch mein problem.
warum funktioniert es mit einem stringgrid aber nicht mit einer listbox?
|
|
Stinger47 
      
Beiträge: 102
|
Verfasst: Do 29.11.07 20:31
weiß jemand wie ich das anders machen müsste?...
hänge leider immernoch darüber und weiß echt nicht mehr weiter...
wäre nett wenn ihr mir helfen könntet...danke
|
|
Marc.
      
Beiträge: 1876
Erhaltene Danke: 129
Win 8.1, Xubuntu 15.10
|
Verfasst: Do 29.11.07 20:50
Warum eigentlich zwei For-Schleifen? Was hälst Du denn davon deine eine Schleife solange laufen zu lassen, bis alles sortiert ist.
Sprich, wir führen eine Boolische-Variable completed zusammen mit einer Repeat-Until-Schleife ein:
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 bsort(s: TStrings); var i: byte; temp: string; completed: boolean; begin repeat completed := true; for i := 0 to s.Count-2 do begin if s.Strings[i] > s.Strings[i+1] then begin temp := s.Strings[i]; s.Strings[i] := s.Strings[i+1]; s.Strings[i+1] := temp;
completed := false; end; end; until completed = true; end; |
Bei s (TStrings) wird meines Erachtens nur die Referenz übergeben, sodass sich der Sortiervorgang letzendlich direkt auf Deine Listbox Items bezieht.
Ansonsten schaut doch der Code im Prinzip genauso aus wie Deiner, mit dem Unterschied der einen Schleife.
Warum es nun aber bei Deinem StringGrid funktioniert, kann ich aber mir imo nicht erklären.
Hoffe Dir aber geholfen zu haben.
Grüße
Marc
Zuletzt bearbeitet von Marc. am Do 29.11.07 21:03, insgesamt 1-mal bearbeitet
|
|
Stinger47 
      
Beiträge: 102
|
Verfasst: Do 29.11.07 20:58
muss dich leider enttäuschen zumindest bei mir funktioniert es nicht...
hast du deinen code mal bei dir getestet?...
|
|
Marc.
      
Beiträge: 1876
Erhaltene Danke: 129
Win 8.1, Xubuntu 15.10
|
Verfasst: Do 29.11.07 21:00
Ja, habe ich, sonst hätte ich auch nicht gepostet.
Bei mir läuft es wirklich einwandfrei. Wie hast Du denn die Prozedur aufgerufen? Irgendwas verändert?
Grüße
Marc
|
|
Stinger47 
      
Beiträge: 102
|
Verfasst: Do 29.11.07 21:07
war mir nicht ganz sicher und habe deine procedure einmal abgeändert, sodass bei jedem s halt listbox1.items stand und einmal hab ich versucht sie folgendermaßen aufzurufen
Delphi-Quelltext 1:
| bsort(listbox1.items); |
|
|
Marc.
      
Beiträge: 1876
Erhaltene Danke: 129
Win 8.1, Xubuntu 15.10
|
Verfasst: Do 29.11.07 21:13
Inwiefern funktioniert es denn nicht? Wird nicht sortiert oder kommt eine Fehlermeldung?
Ich wüsste jetzt nicht, warum es bei Dir nicht funktionieren sollte. *confused*
Grüße
|
|
Stinger47 
      
Beiträge: 102
|
Verfasst: Fr 30.11.07 00:44
es gibt keine fehlermeldung und er fängt auch an zu sortieren allerdings sortiert er wieder nicht richtig...
werde morgen mal das prog reinstellen aber morgen erst... 
|
|
Lannes
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: Fr 30.11.07 01:00
Hallo,
Stinger47 hat folgendes geschrieben: | warum funktioniert es mit einem stringgrid aber nicht mit einer listbox? |
weil in der internen Funktion StringGrid.GetCells die Zugriffsverletzung abgefangen und ein Leerstring zurückgegeben wird.
z.B. zum Testen:
Delphi-Quelltext 1:
| showmessage(StringGrid1.Cells[1000000,1000000]); |
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
Stinger47 
      
Beiträge: 102
|
Verfasst: Fr 30.11.07 01:27
dankeschön...
immerhin weiß ich jetzt warum es nicht geklappt hat...
kann ich die zugriffverletzung bei der listbox irgendwie umgehen oder ist es dann einfach schlauer auf stringgrid auszuweichen?
|
|
PeterPain
      
Beiträge: 83
|
Verfasst: Fr 30.11.07 02:17
Stinger47 hat folgendes geschrieben: | dankeschön...
immerhin weiß ich jetzt warum es nicht geklappt hat...
kann ich die zugriffverletzung bei der listbox irgendwie umgehen oder ist es dann einfach schlauer auf stringgrid auszuweichen? |
schlauer wäre es gründlich zu lesen was man dir gesagt hat
Mal ein plastisches Beispiel um deutlich zu machen wo das problem ist. Sagen wir die Listbox hat 10 einträge (Count = 10), dann bedeutet das, dass die indizes 0 bis 9 gültig sind. Da deine Schleife bis Count - 1(= 9) geht und du nochmal ein + 1 draufsetzt, greifst du auf Index 10 zu, der wie oben geschrieben ungültig ist, daraus resultiert dann die Zugrifssverletzung. Die Lösung ist es nun natürlich nicht ein StringGrid zu verwenden, sondern die schleife, wie schon vorgeschlagen, anzupassen. Ein to Count - 2 und dieses problem ist Geschichte.
Der Code von Marc sollte eigentlich laufen, ist allerdings nicht optimal, da die innere schleife nicht immer bis zum Ende laufen muss, da nach dem ersten durchlauf das erste (respektive das letzte) Item das kleinste (respektive das grösste  ) Item ist, und so weiter.
|
|
Stinger47 
      
Beiträge: 102
|
Verfasst: Fr 30.11.07 13:04
glaub ich muss mich entschuldigen...ich habe ganz vergessen das bei alphabetischer sortierung die 11 vor der 2 kommt ich aber nummerisch sortieren wollte...tut mir leid, hatte den unterschied total vergessen nun klappt es auch bei mir mit -2 dankeschön... 
|
|