Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wie oft ist ein Zeichen in einem String (https://www.delphipraxis.net/85075-wie-oft-ist-ein-zeichen-einem-string.html)

uplink 25. Jan 2007 15:52


Wie oft ist ein Zeichen in einem String
 
Hallöle,

wollt mal wissen ob es eine Funktion gibt, dir mir sagt wie oft ein Zeichen in einem String vorkommt?
mfg Uplink

mkinzler 25. Jan 2007 15:56

Re: Wie oft ist ein Zeichen in einem String
 
Stndardmäßig glaube nicht, kann aber mit pos/posex leicht selbst geschrieben werden.

Muetze1 25. Jan 2007 15:57

Re: Wie oft ist ein Zeichen in einem String
 
Delphi-Quellcode:
Function CountChar(Const AString: String; Const AChar: Char): Integer;
Var
  lStr: PChar;
Begin
  Result := 0;

  lStr := PChar(AString);

  If Assigned(lStr) Then
  Begin
    While ( lStr^ <> #0 ) Do
    Begin
      If lStr^ = AChar Then
        Inc(Result);

      Inc(lStr);
    End;
  End;  
End;

Nils_13 25. Jan 2007 15:58

Re: Wie oft ist ein Zeichen in einem String
 
Delphi-Quellcode:
function bla(s : String; z : String) : Integer;
var i : Integer;
begin
  Result := 0;
  for i := 1 to Length(s) do
  begin
    if s[i] = z then
      inc(Result);
  end;
end;

procedure TfrmMain.Button1Click(Sender: TObject);
begin
  bla('asbsdddds', 'd');
end;
Mist zu spät...

cruiser 25. Jan 2007 15:58

Re: Wie oft ist ein Zeichen in einem String
 
Delphi-Quellcode:
function CountSubStr(SubStr, Str: string): integer;
begin
  Result := 0;
  while pos(SubStr, Str) > 0 do
  begin
    Result := Result + 1;
    Str := Copy(Str, Pos(SubStr, Str) + Length(SubStr), Length(Str));
  end;
end;

uplink 25. Jan 2007 15:59

Re: Wie oft ist ein Zeichen in einem String
 
Ok thx @all, jetz hab ich ja ne Auswahl :)
Danke an euch, dass es so schnell ging.
Mfg Uplink.

dominikkv 25. Jan 2007 16:00

Re: Wie oft ist ein Zeichen in einem String
 
oder so:
Delphi-Quellcode:
function Zeichen(const s: String; const z: Char): Integer;
var
  I: Integer;
begin
result := 0;
for I := 1 to length(s) do
  if s[i] = z then inc(result);
end;

Muetze1 25. Jan 2007 16:01

Re: Wie oft ist ein Zeichen in einem String
 
Da würde ich glatt mal frech fragen: wer hat die schnellste?

xZise 25. Jan 2007 16:04

Re: Wie oft ist ein Zeichen in einem String
 
Zitat:

Zitat von dominikkv
oder so:
Delphi-Quellcode:
function Zeichen(const s: String; const z: Char): Integer;
var
  I: Integer;
begin
result := 0;
for I := 1 to length(s) do
  if s[i] = z then inc(result);
end;

Gabs schonmal:

Zitat:

Zitat von Nils_13
Delphi-Quellcode:
function bla(s : String; z : String) : Integer;
var i : Integer;
begin
  Result := 0;
  for i := 1 to Length(s) do
  begin
    if s[i] = z then
      inc(Result);
  end;
end;

Wer es nicht sieht, einfach Umstellen (Gleicher Code nur andere Formatierung!!!):
Delphi-Quellcode:
function Zeichen(const s: String; const z: Char): Integer;
var
  I: Integer;
begin
  result := 0; // Tab
  for I := 1 to length(s) do // Tab
  // kein Begin, aber irrelevant
    if s[i] = z then  // Tab & umgebrochen!
      inc(result); // Umgebrochen
  // ein end, aber irrelevant
end;
Obwohl die inrementiertung doch eigentlich schneller gehen könnte ... Oder nicht (x := x + 1)?

Nils_13 25. Jan 2007 16:06

Re: Wie oft ist ein Zeichen in einem String
 
Wo gab es den schonmal ? Vlt. in einem anderen Thread, aber ich habe doch schneller gepostet :P

cruiser 25. Jan 2007 16:06

Re: Wie oft ist ein Zeichen in einem String
 
Bei meiner könnt man nich das Result erhöhen mit Inc() machen... und evtl. PosEx statt Pos + Copy verwenden... ansonsten läuft die auch für Fragen wie "Wie oft ist
im Quelltext?" ;)

xZise 25. Jan 2007 16:09

Re: Wie oft ist ein Zeichen in einem String
 
Zitat:

Zitat von Nils_13
Wo gab es den schonmal ? Vlt. in einem anderen Thread, aber ich habe doch schneller gepostet :P

Ich bezog es auf den 1. Code ;) Das er schonmal, von dir, gepostet wurde ^^

dominikkv 25. Jan 2007 16:12

Re: Wie oft ist ein Zeichen in einem String
 
[quote="xZise"]
Zitat:

Zitat von dominikkv
Gabs schonmal:

das sah vor 2 minuten noch anders aus :wink:

Zitat:

Zitat von Muetze1
Da würde ich glatt mal frech fragen: wer hat die schnellste?

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  Start: TTime;
begin
Start := Now;
for I := 1 to 100000000 do
  Zeichen('abcabcabcabcabcabcabcabcabcabc', 'a');
label1.Caption := TimeToStr(Now-Start);
end;
-> 7 sekunden

Matze 25. Jan 2007 16:17

Re: Wie oft ist ein Zeichen in einem String
 
Wenn du eine Geschwindigkeitsmessung durchführen willst, kannst du TTime eigentlich vergessen. Nimm lieber Delphi-Referenz durchsuchenGetTickCount.

xZise 25. Jan 2007 16:21

Re: Wie oft ist ein Zeichen in einem String
 
Zitat:

Zitat von Matze
Wenn du eine Geschwindigkeitsmessung durchführen willst, kannst du TTime eigentlich vergessen. Nimm lieber Delphi-Referenz durchsuchenGetTickCount.

Oder noch besser: GetThreadTimes ^^

Tut über Threads... Und dabei ist eine Zeitberechnung ;)

shmia 25. Jan 2007 16:21

Re: Wie oft ist ein Zeichen in einem String
 
Dann muss ich doch noch einen draufsetzen.
Im Prinzip zwar das Gleiche, aber StrCharsCount zählt gleich mehrere Zeichen auf einmal.
Delphi-Quellcode:
function StrCharCount(const S: string; C: Char): Integer;
var
  I: Integer;
begin
  Result := 0;
  for I := 1 to Length(S) do
    if S[I] = C then
      Inc(Result);
end;

function StrCharsCount(const S: string; Chars: TSysCharSet): Integer;
var
  I: Integer;
begin
  Result := 0;
  for I := 1 to Length(S) do
    if S[I] in Chars then
      Inc(Result);
end;

anzahl := StrCharsCount('Delphi2007', ['0'..'9']); // ergibt 4
Kopiert aus der JCL. :angel2:

SirThornberry 25. Jan 2007 16:22

Re: Wie oft ist ein Zeichen in einem String
 
Dem Fragesteller ist mit den Lösungen eigentlich recht wenig geholfen. Er kann sich die Funktionen kopieren aber der Lerneffekt ist fast 0

sirius 25. Jan 2007 16:32

Re: Wie oft ist ein Zeichen in einem String
 
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var s:string;
    i:integer;
    a:array[0..4] of cardinal;
begin
  setlength(s,100000);
  for i:=1 to 100000 do s[i]:=chr(i mod 10 +60);
  memo1.Clear;

  a[0]:=gettickcount;
  for i:=1 to 1000 do Zeichen(s,'A');
  a[1]:=gettickcount;
  for i:=1 to 1 do countsubstr('A',s);
  a[2]:=gettickcount;
  for i:=1 to 1 do bla(s,'A');
  a[3]:=gettickcount;
  for i:=1 to 1000 do countchar(s,'A');
  a[4]:=gettickcount;
  for i:=1 to 4 do memo1.lines.add(inttostr(a[i]-a[i-1]));




end;
Sieger ist "Zeichen" mit etwa 140ms
Zweiter ist "countchar" mit etwa 200ms
Dritter ist "bla" mit etwa 31ms *1000 ==>31s
Vierter ist "Countsubstr" mit 953ms *1000 ==>953s
Und wir haben keinen Letzten!

zur Verteidigung von countsubstr muss man noch erwähnen, dass er statt Zeichen zu zählen, gleich ganze Teilstrings gezählt hat (wie ja auch der Titel sagt)

(Mehr Aufwand für die Zeitrechnung wollte ich nicht treiben)

cruiser 25. Jan 2007 17:25

Re: Wie oft ist ein Zeichen in einem String
 
Und dass ich den uralten Code wirklich langsam mal optimieren muss ;)

Edit: Okay.. ich fordere ein neues Rennen :lol:

Neuer Code:

Delphi-Quellcode:
function CountSubStr(SubStr, Str: string): integer;
var
  Offset: Cardinal;
  l: Integer;
begin
  l := Length(SubStr);
  Offset := 1;
  Result := 0;
  repeat
    Offset := PosEx(SubStr, Str, Offset);
    if Offset > 0 then
    begin
      Inc(Result);
      Inc(Offset, l);
    end;
  until Offset = 0;
end;

dominikkv 25. Jan 2007 17:52

Re: Wie oft ist ein Zeichen in einem String
 
Zitat:

Zitat von cruiser
Und dass ich den uralten Code wirklich langsam mal optimieren muss ;)

Edit: Okay.. ich fordere ein neues Rennen :lol:

hehe...
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  s: String;
  tick: Cardinal;
begin
  setlength(s,100000);
  for i:=1 to 100000 do
    s[i]:=chr(i mod 10 +60);
  tick := GetTickCount;
  for I := 1 to 1000 do
    CountSubStr('A', s);
  label1.Caption := IntToStr(GetTickCount - Tick);
end;
ich komme auf 203 ms...

cruiser 25. Jan 2007 21:07

Re: Wie oft ist ein Zeichen in einem String
 
Zitat:

Zitat von SirThornberry
Dem Fragesteller ist mit den Lösungen eigentlich recht wenig geholfen. Er kann sich die Funktionen kopieren aber der Lerneffekt ist fast 0

Hast du eigentlich recht... mh... ich kommentier mal meine Methode aus:

Delphi-Quellcode:
function CountSubStr(const SubStr, InStr: string): Cardinal;
var
  // aktuelle Position und Länge des Suchstrings als Cardinal
  Offset, Len: Cardinal;
begin
  // Länge des Suchstrings vorberechnen
  Len := Length(SubStr);
  // Aktuelle Position auf das erste Zeichen setzen
  Offset := 1;
  // Ergebnis ist erst mal 0
  Result := 0;
  // Block wiederholen bis (> 1 <)
  repeat
    // Die Position des nächsten Suchstrings merken
    // PosEx fängt bei der alten Position an zu suchen
    Offset := PosEx(SubStr, InStr, Offset);
    // Wenn ein Suchstring gefunden wurde (Offset ist größer 0)
    if Offset > 0 then
    begin
      // Ergebnis erhöhen
      Inc(Result);
      // Position um die Länge des Suchstrings erhöhen
      Inc(Offset, Len);
    end;
  // (> 1 <) Wenn die Aktuelle Position 0 ist (d.h. es wurde kein Suchstring mehr gefunden) steige aus der Schleife aus
  until Offset = 0;
end;

sirius 26. Jan 2007 08:18

Re: Wie oft ist ein Zeichen in einem String
 
Zitat:

Zitat von cruiser
Und dass ich den uralten Code wirklich langsam mal optimieren muss ;)

Edit: Okay.. ich fordere ein neues Rennen :lol:

Neuer Code:

Delphi-Quellcode:
function CountSubStr(SubStr, Str: string): integer;
var
  Offset: Cardinal;
  l: Integer;
begin
  l := Length(SubStr);
  Offset := 1;
  Result := 0;
  repeat
    Offset := PosEx(SubStr, Str, Offset);
    if Offset > 0 then
    begin
      Inc(Result);
      Inc(Offset, l);
    end;
  until Offset = 0;
end;

Du vergleichst immer noch strings. Das dauert zwangsläufig länger. Da brauch ich gar kein neues Rennen starten.

cruiser 26. Jan 2007 08:23

Re: Wie oft ist ein Zeichen in einem String
 
PosEx arbeitet intern auf Pointer-Basis. Ich komme mit deinem Testlauf auf meiner alten Mühle trotz 1000 Wiederholungen auf ~500 ms.

Edit: Okay... hab mich geirrt. Trotzdem ist der Code um längen schneller als der Pos+Copy-Code. Das Copy hat die meiste Zeit geschluckt, nicht das suchen an sich.

Edit2: Hab mal deinen Test übernommen, hier die Ergebnisse auf meiner Maschine:

Code:
1.) Zeichen (1000 Durchläufe): ~312 ms
2.) StrCharCount (1000 Durchläufe): ~350 ms
2.) CountChar (1000 Durchläufe): ~375 ms
3.) CountSubStr (1000 Durchläufe): ~547 ms
4.) Bla (1 Durchlauf): ~16 ms (1000 Durchläufe: ~ 16 sek)

himitsu 26. Jan 2007 16:36

Re: Wie oft ist ein Zeichen in einem String
 
In Sachen CountSubStr gibt's och noch was in der CodeLib :angel:
> http://www.delphipraxis.net/internal...ct.php?t=61002

Helmi 26. Jan 2007 16:50

Re: Wie oft ist ein Zeichen in einem String
 
hab auch noch einen:
http://www.swissdelphicenter.ch/de/showcode.php?id=1501


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:01 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz