Entwickler-Ecke
Algorithmen, Optimierung und Assembler - Anzahl von TStringList Items
ggehrma - Mi 14.09.05 16:07
Titel: Anzahl von TStringList Items
Hallo,
Ich habe eine TStringList in der einige Strings mehrmals vorkommen. Jetzt würde ich gerne wissen, welcher String wie oft in der Stringlist vorkommt.
Hat da jemand eine Idee, wie ich das anstellen kann?
mfg, ggehrma.
PS: Bitte keinen Code, sondern nur Gedankenanregungen.
Moderiert von
Gausi: Topic aus VCL (Visual Component Library) verschoben am Mi 14.09.2005 um 16:20
Grishnak - Mi 14.09.05 16:14
Ansatz: Alle Strings über das .Text- oder .CommaText-Property auslesen und darin mittels PosEx suchen.
Gausi - Mi 14.09.05 16:19
Ich würde eine neue Struktur nehmen, in etwa
Delphi-Quelltext
1: 2: 3:
| Stringmitzahl = class(TObject) meinstring: string; Anzahl: integer; |
Dann anfangen die Stringliste durchzugehen. Dabei für jeden String überprüfen: "Habe ich den schon erfasst?" Wenn ja: Anzahl in dem entsprechenden Objekt erhöhen. Wenn nicht: Neues Object mit dem String erstellen, und in eine TObjectlist reinpacken.
Wahrscheinlich gehts auch einfacher und schneller. Ist nur ein Gedanke :wink:
ggehrma - Mi 14.09.05 17:12
Also .CommaText bringt mir nix, da es nix zu "CommaTexten" gibt. Hier mal ein Beispiel, wie meine Stringlist aussieht:
Eintrag String
0 a+bc0
1 e-fg-1
2 a+bc0
3 h+ij1
4 k-lm0
5 e-fg-1
6 a+bc0
7 n-op1
Und jetzt möchte ich halt wissen, wie oft z.B. der String a+bc0 vorkommt (hier wäre es ja 3mal).
Sprint - Mi 14.09.05 17:51
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| function GetValueCount(AStrings: TStrings; const AValue: String): Integer; var I: Integer; begin
Result := 0; for I := 0 to AStrings.Count - 1 do if AStrings.Strings[I] = AValue then Inc(Result);
end; |
Das ist vielleicht nicht besonders effizient, sollte aber für kurze StringListen langen.
alzaimar - Mi 14.09.05 17:52
Tipp: Sortiere die Liste doch einfach und dann gehst Du von vorne nach hinten. Während des Durchlaufens prüfst Du, ob der aktuelle String S[i] = S[i-1] ist.
Grishnak - Mi 14.09.05 18:14
| ggehrma hat folgendes geschrieben: |
| Also .CommaText bringt mir nix, da es nix zu "CommaTexten" gibt. Hier mal ein Beispiel, wie meine Stringlist aussieht: |
der .CommaText würde nach deinem Beispiel so aussehen:
Quelltext
1:
| 'a+bc0,e-fg-1,a+bc0,h+ij1,k-lm0,e-fg-1,a+bc0,n-op1' |
Jetzt gehst du alle Strings deiner Stringliste durch und suchst per PosEx in diesem .CommaText danach!
Lannes - Mi 14.09.05 22:38
Hallo,
diese Funktion gibt die Anzahl der Items aus,
mit dem Vorteil das die Original-Stringliste unsortiert bleibt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| function StrInStrList(s: String;sL: TStringlist): Integer; var aStringList : TStringlist; pos,i : Integer; begin aStringList := TStringlist.Create; try aStringList.Text := sL.Text; aStringList.Sort; pos := aStringList.IndexOf(s); if pos <> -1 then begin i := 1; while aStringList[pos+i] = s do inc(i); result := i; end else result := 0; finally aStringList.Free; end; end; |
alzaimar - Mi 14.09.05 22:47
Titel: Re: Anzahl von TStringList Items
@Lannes: Jetzt hast Du ihm den Spass verdorben tzz tzz tzz.
ggehrma hat folgendes geschrieben: |
| ...PS: Bitte keinen Code, sondern nur Gedankenanregungen. |
UGrohne - Mi 14.09.05 22:56
Hab auch noch ne Anregung:
Also wenn es fuer etwas größeres sein sollte, dann wuerde ich wahrscheinlich eine Klassse von TStringList ableiten, die Add-Funktion ueberschreiben, ein Integer-Array hinzufügen (für die Anzahl) und beim Einfügen den Vorschlag von Gausi übernehmen. So hättest Du immer noch eine Klasse, aber mit allen Infos, die Du brauchst.
Lannes - Mi 14.09.05 23:13
Hallo,
@alzaimar: war nicht meine Absicht :oops:
alzaimar - Do 15.09.05 08:42
UGrohne hat folgendes geschrieben: |
Hab auch noch ne Anregung:
Also wenn es fuer etwas größeres sein sollte, dann wuerde ich wahrscheinlich eine Klassse von TStringList ableiten, die Add-Funktion ueberschreiben, ein Integer-Array hinzufügen (für die Anzahl) und beim Einfügen den Vorschlag von Gausi übernehmen. So hättest Du immer noch eine Klasse, aber mit allen Infos, die Du brauchst. |
Jo, oder einfach
Integer (MyStringList.Objects[x]) verwenden
ggehrma - Do 15.09.05 13:24
Hallo,
danke für eure vielen Vorschläge. Hab mir jetzt selber was zusammengebastelt, was aber doch auf vielem von dem, was ihr vorgeschlagen habt basiert.
Hier der Code (ist leider etwas aus dem Zusammenhang gerissen):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| PROCEDURE Auswertung(Formulierung: String); BEGIN IF FormulierungsListe.IndexOf(Formulierung) = -1 THEN BEGIN FormulierungsListe.Add(Formulierung); Anzahl.Add('1'); END ELSE Anzahl.Strings[FormulierungsListe.IndexOf(Formulierung)] := IntToStr(StrToInt(Anzahl.Strings[FormulierungsListe.IndexOf(Formulierung)])+1); END; |
FormulierungsListe und Anzahl sind zwei StringListen. Ich weiß, es geht sicherlich auch noch schöner. Aber das erschien mir so am einfachsten.
Moderiert von
Christian S.: Code- durch Delphi-Tags ersetzt.
alzaimar - Do 15.09.05 14:03
So ist es schon ok. Hier noch mein Vorschlag:
Anstatt der separaten Liste 'Anzahl' kannst du ruhig die Objects-Eigenschaft der Stringliste benutzen.
Weiterhin wird der IndexOf nur 1x berechnet. Stell Dir vor, die Liste sei 100000000 Elemente lang, dann macht das schon viel aus.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| PROCEDURE Auswertung(Formulierung: String); Var i : Integer;
BEGIN i := FormulierungsListe.IndexOf(Formulierung); IF i = -1 THEN FormulierungsListe.AddObject (Formulierung, Pointer (1)); ELSE Formulierungsliste.Objects[i] := Pointer (Integer (FormulierungsListe.Objects[i]) END;
Function Anzahl (i : Integer) : Integer; Begin Result := Integer (Formulierungsliste.Objects[i]) End; |
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!