Autor Beitrag
ggehrma
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 111

WinXP
D2005 Pers.
BeitragVerfasst: 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 user profile iconGausi: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8553
Erhaltene Danke: 479

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Mi 14.09.05 16:19 
Ich würde eine neue Struktur nehmen, in etwa

ausblenden 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:

_________________
We are, we were and will not be.
ggehrma Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 111

WinXP
D2005 Pers.
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: Mi 14.09.05 17:51 
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 221

Windows XP Home
Delphi 7 PE, Delphi 2005 PE
BeitragVerfasst: 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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Mi 14.09.05 22:38 
Hallo,

diese Funktion gibt die Anzahl der Items aus,
mit dem Vorteil das die Original-Stringliste unsortiert bleibt:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Mi 14.09.05 22:47 
@Lannes: Jetzt hast Du ihm den Spass verdorben tzz tzz tzz.
user profile iconggehrma hat folgendes geschrieben:
...PS: Bitte keinen Code, sondern nur Gedankenanregungen.
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2352
Erhaltene Danke: 4

Win XP, 95, 3.11, IE6
D3 Prof, D4 Standard, D2005 PE, TurboDelphi, Lazarus, D2010
BeitragVerfasst: Mi 14.09.05 23:13 
Hallo,

@alzaimar: war nicht meine Absicht :oops:

_________________
MfG Lannes
(Nichts ist nicht Nichts) and ('' <> nil ) and (Pointer('') = nil ) and (@('') <> nil )
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Do 15.09.05 08:42 
user profile iconUGrohne 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 111

WinXP
D2005 Pers.
BeitragVerfasst: 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):
ausblenden 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 user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.

_________________
"...To boldly go where no one has gone before."
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: 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.

ausblenden 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;