Autor Beitrag
sky21
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 141

W7
D2010, XE2
BeitragVerfasst: Do 30.04.09 11:23 
Ich bin Programmierer und deshalb faul ;-) Weshalb gibt es nicht bereits eine Systemfunktion, welche mir bei einem String die Anzahl gesuchter Elemente zurück gibt? Ich habe zumindest nichts brauchbares in dieser Richtung gefunden.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
Inputstring = 'halloWelt';
SearchChar := 'l'//  l= "el" und nicht "eins"

res := GetNumberOfChars(Inputstring, SearchChar); // res = 3


Muss man wirklich immer alles selber machen? Ok, Anstatt Zeit für diesen Beitrag aufzuwenden, hätte man diese auch gleich benutzen können, die Funktion selber zu schreiben, harr harr.

Moderiert von user profile iconAXMD: Delphi-Tags hinzugefügt
Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Do 30.04.2009 um 17:00
thepaine91
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Do 30.04.09 12:20 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
function TForm1.SubstringFinden(const Text, Suchstring: String): integer;
var i, Anzahl: integer;
begin
  Anzahl := 0;
  for i := 1 to length(Text) - length(Suchstring) +1 do
    if copy(Text, i, length(Suchstring)) = Suchstring then inc(Anzahl);// gibt sicher was besseres als copy grad nur keine zeit zu gucken
end;

damit du faul bleiben kannst ^^ aber wenns da doch eine Fertige funktion geben sollte lasst es mich wissen :D


Zuletzt bearbeitet von thepaine91 am Do 30.04.09 12:50, insgesamt 1-mal bearbeitet
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Do 30.04.09 12:27 
Gefällt mir aus verschiedensten Gründen absolut nicht.
Warum ist Suchstring ein Var-Parameter, warum wird mein ursprünglicher String verändert, kann das auch nur im entferntesten Sinnvoll sein? :autsch:
Mal ausprobiert: Es ist unendlich langsam, was auch kein Wunder ist, da es ja Elemente aus dem String löscht, wodurch der komplette String hin- und herkopiert werden muss.
... Ok, ich breche meinen ursprünglichen Test ab, 50000 Durchgänge dauern bei mir mehr als 1 Minute.
... 5000 Durchgänge. 22,6 Sekunden (!), im Vergleich dazu
ausblenden Delphi-Quelltext
1:
2:
3:
    for i := 1 to Length(s) do
      if s[i] = ' ' then
        inc(m1);

ebenfalls 5000 Durchgänge dauerte 47 ms (!)

:roll:

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
thepaine91
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Do 30.04.09 12:34 
Das kommt noch aus anfangszeiten meiner Programmierung war nur copy paste ^^
Das deine so viel schneller ist wundert mich dann auch nicht ^^
Aber ich editier sie mal so das es sinnvoll ist

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function TForm1.SubstringFinden(const Text, Suchstring: String): integer;
var i, Anzahl: integer;
begin
  Anzahl := 0;
  for i := 1 to length(Text) - length(Suchstring) +1 do
    if copy(Text, i, length(Suchstring)) = Suchstring then inc(Anzahl);
// gibt sicher was besseres als copy grad nur keine zeit zu gucken
  Result := Anzahl // so :D das wichtigste vergessen :P
// soweit ich weis könnte man Anzahl auch weglassen und es so lösen 
  Result:= 0;
  .... then inc(Result);
// dann kann man die letzte Zeile sparen :D (nicht ausprobiert)
end;


Zuletzt bearbeitet von thepaine91 am Do 30.04.09 13:02, insgesamt 1-mal bearbeitet
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Do 30.04.09 12:55 
user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Das kommt noch aus anfangszeiten meiner Programmierung war nur copy paste ^^
Das deine so viel schneller ist wundert mich dann auch nicht ^^
Aber ich editier sie mal so das es sinnvoll ist

Deine Funktion arbeitet halt mit einem Suchstring während meine nur einen Char sucht. Wenn's um Strings geht, funktioniert das nicht so einfach. In ADA könnte man einfach die Grenze des Strings als Slice angeben... Aus s(1 .. 5) = 'hallo' wird s(4 .. 5) = 'o', das ist recht schnell. In Delphi gibt es soweit ich weiß auch slices aber ich weiß nicht, wie das geht.

Deine neue Methode brauchte im Test nur 4,4 Sekunden, schon viel besser :zustimm: Optimieren lässt es sich sicherlich mit PosEx... Ich probier mal was :)
Edit: Result := Anzahl; vergessen :rofl:

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 30.04.09 13:00 
Nicht ganz ernst gemeint (bevor jetzt jemand an mir zweifelt :P)

ausblenden Delphi-Quelltext
1:
2:
3:
4:
function CountChars(Haystack: String; Needle: Char): Integer;
begin
    Result := Length(Haystack) - Length(StringReplace(Haystack, Needle, '', [rfReplaceAll]));
end;


Für nicht-überlappende Strings funktioniert auch:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
function CountNonOverlappingStr(Haystack: String; Needle: String): Integer;
begin
    Result := Length(Haystack) - Length(StringReplace(Haystack, Needle, '', [rfReplaceAll]));
end;

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
thepaine91
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Do 30.04.09 13:03 
Hm ich guck auch mal wenn ich Zeit hab ob ich was finde :P und er wollte das ja garnicht mit strings wo du es sagst :D
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Do 30.04.09 13:08 
Auf 93 ms komme ich mit
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function SubstringFinden(Text, Suchstring: String): integer;
var i, Anzahl: integer;
begin
  Anzahl := 0;
  i := Pos(SuchString, Text);
  while i > 0 do
  begin
    inc(Anzahl);
    i := PosEx(Suchstring, Text, i + Length(SuchString));
  end;
  Result := Anzahl;
end;

und mit BenBEs nicht ganz ernst gemeinter Funktion kommt man auf 26 Sekunden :lol:

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
thepaine91
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Do 30.04.09 13:12 
Puhh 93 ms..... geht das nicht schneller ? -.- Ich mein für so ein bisschen String suche will ich ja nicht gleich meinen ganzen Tag vergeuden. Und wenn du hier schon Messwerte raushaust dann bitte auch deine Systemleistung. ^^ Ansonsten kann man damit nix anfangn.
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Do 30.04.09 13:30 
user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Puhh 93 ms..... geht das nicht schneller ?
für 5000 Durchgänge eines 3720 Zeichen langen Strings. 2,2GHz (dualcore, wird ja nur 1 genutzt)

Gern geschehen, übrigens, ich brauch atm keine Stringsuche aber für so freundliche Antworten arbeite ich auch mal gern kostenlos :roll:

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
thepaine91
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Do 30.04.09 13:42 
jayeff liegt an meinem seltsamen Humor. War nicht ernst gemeint. Super Lösung :zustimm:
Außer das mit der Systemleistung ist immer ganz nett zu wissen damit man es wenigstens ein bissel einschätzen kann.

Und ben be deine nicht ganz ernst gemeinte lösung bietet mir nicht ganz richtige Ergebnise :P
JayEff
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Do 30.04.09 14:14 
user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
jayeff liegt an meinem seltsamen Humor. War nicht ernst gemeint. Super Lösung :zustimm:
Jaaa das hab ich zuerst eig auch gedacht... :roll: komisch, dass ich das dann trotzdem nochmal uminterpretiert hab :shock:
Nix für ungut ;)

Ich hab meine Werte eigentlich nur zum Vergleichen angegeben.

Edit: Bei meinem Test funktionierte Ben's Funktion mit Chars, aber die mit Strings ist falsch. Man muss das Endergebniss noch durch die Suchstring-Länge teilen =P

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
thepaine91
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Do 30.04.09 14:51 
:D das erklärt einiges...
BenBe auch wenn es nicht die effektivste Lösung ist immerhin ein einzeiler :D
und ehrlich gesagt hab ich keine Ahnung was du da machst :P war auch zu faul die Delphi Hilfe durchzulesen. ^^
Und die für Strings dann eben so
ausblenden Delphi-Quelltext
1:
2:
3:
4:
function CountNonOverlappingStr(Haystack: String; Needle: String): Integer;
begin
    Result := (Length(Haystack) - Length(StringReplace(Haystack, Needle, '',[rfReplaceAll])))div length(Needle);
end;
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 30.04.09 15:08 
user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
und ehrlich gesagt hab ich keine Ahnung was du da machst :P war auch zu faul die Delphi Hilfe durchzulesen. ^^
Naja, was wird StringReplace schon machen? Richtig: Einen String durch einen anderen ersetzen.

Er ersetzt einfach alle Vorkommen des gesuchten Strings durch '', löscht diese also. Die Differenz aus der Länge vorher und des Strings ohne diese Teile des Strings ist dann die Anzahl der Buchstaben damit. Und geteilt durch die Länge des gesuchten Strings ist das dann dessen Anzahl.
Nersgatt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1581
Erhaltene Danke: 279


Delphi 10 Seattle Prof.
BeitragVerfasst: Do 30.04.09 15:18 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Er ersetzt einfach alle Vorkommen des gesuchten Strings durch '', löscht diese also. Die Differenz aus der Länge vorher und des Strings ohne diese Teile des Strings ist dann die Anzahl der Buchstaben damit. Und geteilt durch die Länge des gesuchten Strings ist das dann dessen Anzahl.

Erinnert mich irgendwie an die Frage, wie Mathematiker Elefanten fangen:
Zitat:

Mathematiker fangen Elefanten, indem sie nach Afrika gehen, alles entfernen, was nicht Elefant ist und ein Element der Restmenge fangen.

_________________
Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
sky21 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 141

W7
D2010, XE2
BeitragVerfasst: Do 30.04.09 15:36 
Hey danke für die vielen Beiträge hier! Mittlerweile habe ich es auch selber implementiert und präsentiere meine Version hier:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
// returns the number of found characters (Note: comparison is case sensitive!)
function GetNumberOfChars(const sInput : stringconst chrSearch : char) : Integer;
var
  i : Integer;

begin
  Result := 0;
  for i:=1 to Length(sInput) do
    if (sInput[i] = chrSearch) then
      Inc(Result);
end;
thepaine91
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Mo 04.05.09 12:38 
Mal eine Frage @jeanicke welche Delphi version benutzt du? Ich finde leider kein PosEx.
Nersgatt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1581
Erhaltene Danke: 279


Delphi 10 Seattle Prof.
BeitragVerfasst: Mo 04.05.09 13:17 
user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Mal eine Frage @jeanicke welche Delphi version benutzt du? Ich finde leider kein PosEx.

Hast Du StrUtils eingebunden?

_________________
Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 04.05.09 13:46 
Und für Delphi 5 oder früher gibts hier einen Ersatz:
www.delphipraxis.net/post409954.html
espen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 90
Erhaltene Danke: 1


D6 Prof./D7 Prof. MSSQL, MySQL
BeitragVerfasst: Mo 04.05.09 14:11 
Hallo,

ich glaube meine Version ist etwas schneller ;-)


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:
23:
24:
25:
26:
27:
function GetNumberOfChars(const aString : Stringconst aChar : Char) : Integer;
var
  FCount : integer;
  FFind  : Integer;
begin
  FCount := 0;
  FFind  := ord(aChar);
  asm
    // ****
    // **** Initialisierung
    // ****
    mov eax, aString // ** Der zu durchsuchende String
    mov ecx, FCount  // ** Ergebnis

    @CNT:                  // ** Schleife
    inc eax                // ** Schleifenzähler inkrementieren
    movzx edx, byte [eax]  // ** n. Zeichen holen
    cmp edx, FFind         // ** Vergleiche n. Zeichen mit Suche
    jne @NXT               // ** Nicht gefunden, springe zu Schleifenende
    inc ecx                // ** Gefunden, Ergebnis inkrementieren
    @NXT:                  // ** Schleifenende
    cmp edx, 0             // ** Ende von String ?
    jne @CNT               // ** Nein, also nächstes Zeichen
    mov FCount, ecx        // ** Fertig, Ergebnis zuweisen
  end;
  Result := FCount;
end;


Gruss.