Autor |
Beitrag |
Terra23
      
Beiträge: 872
Win 8
Delphi 7
|
Verfasst: So 22.02.09 00:12
Hi!
Ich weiß nicht, ob ich in diesem Unterforum richtig bin aber ich poste mal hier (verschieben kann man ja immer noch). Die Suche brachte keine für mich befriedigenden Ergebnisse.
Folgendes Problem:
Ich habe eine ListBox mit X Strings und eine weitere mit Y Strings.
Ich möchte die zweite ListBox nun durchsuchen lassen und zwar nach folgenden Gesichtspunkten:
Es soll geprüft werden, ob ein String aus der ersten ListBox in der zweiten vorhanden ist und falls ja, wie oft dies der Fall ist.
Ich habe schon mehrere Ansätze versucht (mit Repeat, mit For-Schleifen und dergleichen), aber ich kriege das einfach nicht hin.
Ich kann auch gern meinen Quellcode posten, allerdings kriege ich (immer, wenn ich das mache; wirklich IMMER) geschimpft, weil mein Code nicht lesbar genug ist und ich möge doch bitte mir den Thread durchlesen, wie man optisch ansprechenden Code schreibt etc.
Wenn mir jemand nen Hinweis geben könnte, wonach ich suchen soll, wäre mir schon ein wenig geholfen. Wenn jemand nen fertigen Code hat (normalerweise frage ich NIE nach fertigem Code, weil ich weiß, wie ihr dazu steht und weil ich lieber selbst schreibe), wäre das noch besser.
Zur Erläuterung (für alle, denen meine Romane zu unverständlich sind) nochmal das ganze dargestellt:
ListBox1:
Achim
Martin
Eva
Klaus
Nadine
ListBox2:
Achim
Nadine
Eva
Achim
Klaus
Martin
Klaus
Nadine
Martin
Martin
Achim
Eva
Eva
Wenn nun anhand der ersten ListBox die zweite durchsucht wird, müsste (in diesem Beispiel) folgendes Ergebnis rauskommen:
Achim: 3x
Nadine: 2x
Eva: 3x
Klaus: 2x
Martin: 3x
MfG
Terra
_________________ Hasta La Victoria Siempre
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 22.02.09 00:39
Wo ist denn das Problem?  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 TForm148.Button1Click(Sender: TObject);
procedure CountOccurrences(const List1, List2: TStrings; var Result: TStrings); var i, CurIndex: Integer; begin for i := 0 to List1.Count - 1 do Result.AddObject(List1[i], TObject(0)); for i := 0 to List2.Count - 1 do begin CurIndex := Result.IndexOf(List2[i]); if CurIndex >= 0 then Result.Objects[CurIndex] := TObject(Succ(Integer(Result.Objects[CurIndex]))); end; end;
var TempList: TStrings; i: Integer; begin TempList := TStringList.Create; try CountOccurrences(ListBox1.Items, ListBox2.Items, TempList); for i := 0 to TempList.Count - 1 do ShowMessage(TempList[i] + ': ' + IntToStr(Integer(TempList.Objects[i]))); finally TempList.Free; end; end; | Und wenn du nur die Anzahlen haben willst, dann müssen die Strings auch nicht ins Ergebnis rein, dann reicht ein Integerarray: 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:
| procedure TForm148.Button2Click(Sender: TObject); type TIntArray = array of Integer;
procedure CountOccurrences(const List1, List2: TStrings; var Result: TIntArray); var i, CurIndex: Integer; begin for i := 0 to List2.Count - 1 do begin CurIndex := List1.IndexOf(List2[i]); if CurIndex >= 0 then Result[CurIndex] := Succ(Result[CurIndex]); end; end;
var TempList: TIntArray; i: Integer; begin SetLength(TempList, ListBox1.Items.Count); CountOccurrences(ListBox1.Items, ListBox2.Items, TempList); for i := Low(TempList) to High(TempList) do ShowMessage(ListBox1.Items[i] + ': ' + IntToStr(TempList[i])); SetLength(TempList, 0); end; |
|
|
Terra23 
      
Beiträge: 872
Win 8
Delphi 7
|
Verfasst: So 22.02.09 16:03
Das Problem?  Ich habe Delphi nur ein Jahr in der Schule gehabt und habe mir das meiste mit Hilfe eures Forums oder durch ausprobieren beigebracht. Den Code, den du gepostet hast, werde ich mal testen, aber was für dich wie ein einfacher Code aussieht, ist für mich etwas, dass ich erstmal durchschauen muss.
Erstmal danke für die Hilfe. Ich melde mich hier nochmal, ob es klappt oder nicht.
Terra
_________________ Hasta La Victoria Siempre
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 22.02.09 16:20
Was ich mache ist alle Einträge in der zweiten ListBox durchgehen und jeden in der ersten suchen. In der ersten Variante speichere ich die Anzahlen in einer TStringList inkl. der dazugehörigen Strings aus der ersten ListBox, in der zweiten Variante speichere ich nur die Anzahlen.
Bei einer TStringList mache ich mir zunutze, dass man ein Objekt zu jedem Eintrag speichern kann. Das gilt auch für ListBox1.Items zum Beispiel. Jedenfalls ist sowas ein Pointer, und ein Pointer ist ein 4 Byte Integerwert. Also lege ich da keine Adresse eines Objekts (einen Pointer) ab, sondern benutze den Zahlenwert direkt zum Zählen.
Terra23 hat folgendes geschrieben : | aber was für dich wie ein einfacher Code aussieht, ist für mich etwas, dass ich erstmal durchschauen muss.  |
Och, die erste Version ist durch den Trick gar nicht so besonders einfach, schon gar nicht, wenn man vielleicht Pointer gar nicht kennt. Das ist also normal, aber ich denke mal, das verstehst du schon. 
|
|
Terra23 
      
Beiträge: 872
Win 8
Delphi 7
|
Verfasst: So 22.02.09 16:41
Wenn ich deine erste Prozedur aufrufen will, was muss ich denn dann als Parameter für die Variable angeben?
_________________ Hasta La Victoria Siempre
|
|
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 22.02.09 16:56
Keine, Du musst nur in Form148 auf Button1 klicken.
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 22.02.09 17:07
Das ist ja nur ein Beispiel gewesen, meine Form heißt Form148 und der Button Button1, weil ich einfach nur ein neues Projekt erzeugt habe. Und die erste Zeile habe ich dabei gelassen, damit klar ist, dass es sich um einen ButtonClick handelt.
Wenn du deine beiden ListBoxen und nen Button hast, dann musst du den Quelltext nur da reinschreiben.
Und CountOccurrences rufe ich ja selbst auf, da siehst du ja den Aufruf.
|
|
Terra23 
      
Beiträge: 872
Win 8
Delphi 7
|
Verfasst: So 22.02.09 17:19
Also bei deinem Code (jaenicke) treten bei mir folgende Probleme auf. Der erste Code funktioniert zwar super, allerdings kann ich den nicht so verändern, wie ich das gerne hätte.
Es werden zwar beide ListBoxen miteinander verglichen, aber ich möchte, dass dann noch folgendes passiert:
Wenn ein Name mehr als 1x auftaucht, soll der Name entsprechend der Überzahl in eine dritte ListBox übergeben werden, z.B.:
Martin ist 3x vorhanden, darf aber nur 1x vorhanden sein. Nun soll der String "Martin" 2x in die dritte ListBox geschrieben werden.
Das macht mir im Moment sehr zu schaffen.
Bei deinem zweiten Code beschwert sich Delphi darüber, dass TIntArray ein undefinierter Bezeichner wäre. Muss ich noch ne Unit ins Projekt einbinden? Falls ja, welche.
Gruß,
Terra
PS: Was ist bei dir List1 und was ist List2? Ist List1 das, was im Startpost bei mir ListBox1 ist?
_________________ Hasta La Victoria Siempre
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 22.02.09 17:24
Terra23 hat folgendes geschrieben : | Es werden zwar beide ListBoxen miteinander verglichen, aber ich möchte, dass dann noch folgendes passiert:
[...] |
Naja, das Ergebnis durchgehen wie im ersten Beispiel und dann statt das per ShowMessage auszugeben schauen, ob die Anzahl größer 1 ist. Wenn ja, dann nimmst du die Anzahl minus 1 und hast die Anzahl für die dritte ListBox. Ansonsten (wenn die Anzahl genau 1 ist nämlich) musst du nichts tun.
Am einfachsten geht das mit einer for-Schleife von 0 bis Anzahl - 2.
Terra23 hat folgendes geschrieben : | Bei deinem zweiten Code beschwert sich Delphi darüber, dass TIntArray ein undefinierter Bezeichner wäre. Muss ich noch ne Unit ins Projekt einbinden? Falls ja, welche. |
Ähm... jaenicke hat folgendes geschrieben : | Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TForm148.Button2Click(Sender: TObject); type TIntArray = array of Integer;
procedure CountOccurrences(const List1, List2: TStrings; var Result: TIntArray); | |
Terra23 hat folgendes geschrieben : | PS: Was ist bei dir List1 und was ist List2? Ist List1 das, was im Startpost bei mir ListBox1 ist? |
Das sind die Parameter an die Prozedur, das können beliebige TStrings sein, in diesem Fall siehst du doch eigentlich was ich übergebe. Nämlich ListBox1.Items und ListBox2.Items.
|
|
Terra23 
      
Beiträge: 872
Win 8
Delphi 7
|
Verfasst: So 22.02.09 17:58
Hab es hinbekommen. Vielen Dank für deine Hilfe und deine schier unendliche Geduld.
Terra
PS: Er hat sich nicht bei dem von dir orange markierten Teil beschwert, sondern hier:
procedure CountOccurrences(const List1, List2: TStrings; var Result: TIntArray);
_________________ Hasta La Victoria Siempre
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 22.02.09 18:28
Terra23 hat folgendes geschrieben : | PS: Er hat sich nicht bei dem von dir orange markierten Teil beschwert, sondern hier:
procedure CountOccurrences(const List1, List2: TStrings; var Result: TIntArray); |
Ja, ich weiß, aber der markierte Teil ist die bei dir offenbar fehlende Deklaration. Wenn du die genauso dazu geschrieben hättest, dann würde TIntArray auch gefunden werden.
|
|
Terra23 
      
Beiträge: 872
Win 8
Delphi 7
|
Verfasst: Sa 16.02.13 12:57
jaenicke hat folgendes geschrieben : | Wo ist denn das Problem?  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 TForm148.Button1Click(Sender: TObject);
procedure CountOccurrences(const List1, List2: TStrings; var Result: TStrings); var i, CurIndex: Integer; begin for i := 0 to List1.Count - 1 do Result.AddObject(List1[i], TObject(0)); for i := 0 to List2.Count - 1 do begin CurIndex := Result.IndexOf(List2[i]); if CurIndex >= 0 then Result.Objects[CurIndex] := TObject(Succ(Integer(Result.Objects[CurIndex]))); end; end;
var TempList: TStrings; i: Integer; begin TempList := TStringList.Create; try CountOccurrences(ListBox1.Items, ListBox2.Items, TempList); for i := 0 to TempList.Count - 1 do ShowMessage(TempList[i] + ': ' + IntToStr(Integer(TempList.Objects[i]))); finally TempList.Free; end; end; | |
Sag mal, @ jaenicke:
Kannst du mir vielleicht auf die Sprünge helfen, wie ich bestimmte Zeilen dann einfärbe?
Den Code fürs Einfärben habe ich schon, ich weiß allerdings nicht, wo / wie der untergebracht werden muss und im Moment stehe ich total auf dem Schlauch.
Damit du weißt, worum es geht, ein Beispiel:
Ich habe eine Liste mit Namen, nennen wir sie "Liste_Keywords"...
Armin
Eva
Nils
Oliver
Ich habe eine weitere Liste mit Namen, nennen wir sie "Liste_Namen"...
Andy
Armin
Dave
Edgar
Eva
Jan
Nils
Oliver
Ich vergleiche nun die Listen mit deinem Code, was sehr gut funktioniert.
Nun möchte ich aber nicht nur angezeigt bekommen, wie oft ein Name in Liste_Namen steht sondern ich möchte in Liste_Namen alle Zeilen, die auch in Liste_Keywords sind, einfärben.
Dein Code funktioniert sehr gut, allerdings ist "TempList[i"] ja nicht gleichbedeutend mit "Liste_Namen[i]", da Liste_Namen ja mehr Items beinhaltet als TempList.
Magst du mir weiterhelfen?
_________________ Hasta La Victoria Siempre
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 17.02.13 00:57
Moin!
Bitte erstelle für jede deiner Fragen ein separates Topic, da die Diskussion mehrerer Fragen in einem Topic für gewöhnlich für Verwirrung und Durcheinander sorgt.  Danke!
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Dieses Thema ist gesperrt, Du kannst keine Beiträge editieren oder beantworten.
Das Thema wurde von einem Team-Mitglied geschlossen. Wenn du mit der Schließung des Themas nicht einverstanden bist, kontaktiere bitte das Team.
|
|