| Autor |
Beitrag |
ggehrma
      
Beiträge: 111
WinXP
D2005 Pers.
|
Verfasst: Mi 14.09.05 16:07
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
_________________ "...To boldly go where no one has gone before."
|
|
Grishnak
      
Beiträge: 221
Windows XP Home
Delphi 7 PE, Delphi 2005 PE
|
Verfasst: Mi 14.09.05 16:14
Ansatz: Alle Strings über das .Text- oder .CommaText-Property auslesen und darin mittels PosEx suchen.
_________________ Mach' etwas idiotensicher und irgendjemand erfindet einen besseren Idioten!
|
|
Gausi
      
Beiträge: 8553
Erhaltene Danke: 479
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: 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 
_________________ We are, we were and will not be.
|
|
ggehrma 
      
Beiträge: 111
WinXP
D2005 Pers.
|
Verfasst: 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).
_________________ "...To boldly go where no one has gone before."
|
|
Sprint
      
Beiträge: 849
|
Verfasst: 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.
_________________ Ciao, Sprint.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: 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
      
Beiträge: 221
Windows XP Home
Delphi 7 PE, Delphi 2005 PE
|
Verfasst: 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
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: 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; |
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mi 14.09.05 22:47
@Lannes: Jetzt hast Du ihm den Spass verdorben tzz tzz tzz.
ggehrma hat folgendes geschrieben: | | ...PS: Bitte keinen Code, sondern nur Gedankenanregungen. |
|
|
UGrohne
      

Beiträge: 5502
Erhaltene Danke: 220
Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
|
Verfasst: 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
      
Beiträge: 2352
Erhaltene Danke: 4
Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
|
Verfasst: Mi 14.09.05 23:13
Hallo,
@alzaimar: war nicht meine Absicht 
_________________ MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: 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 
      
Beiträge: 111
WinXP
D2005 Pers.
|
Verfasst: 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.
_________________ "...To boldly go where no one has gone before."
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: 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; |
|
|