Entwickler-Ecke

Algorithmen, Optimierung und Assembler - ...Vorkommen eines Buchstabens in einem String zählen


jaenicke - Mo 04.05.09 22:17
Titel: ...Vorkommen eines Buchstabens in einem String zählen
Diese kleine Funktion zählt die Anzahl der Vorkommen des Buchstabens aChar in aString. Dies funktioniert sowohl mit Delphi 2007 und früher und 1-Byte-Chars als auch mit Delphi 2009 und Unicode-Chars mit 2 Byte.

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:
28:
29:
30:
31:
32:
33:
34:
35:
function CountCharOccurrences(const aChar: Char; const aString: String): Integer;
asm
  // Wenn edx 0 ist, abbrechen und 0 zurückgeben
  or edx, edx
  jnz @@ValidString
  xor eax, eax
  ret
  @@ValidString:

  // Register sichern
  push edi

  // in al ist bereits aChar drin, fehlt für scasb noch der zu scannende
  // String in edi
  mov edi, edx
  mov ecx, dword ptr [edx - $04]

  xor edx, edx // Zähler auf 0

  @@repeat:
  inc edx
  {$ifdef UNICODE}
  repne scasw
  {$else}
  repne scasb
  {$endif}
  jz @@repeat

  // Ergebnis zurückgeben
  dec edx
  mov eax, edx

  // Register wiederherstellen
  pop edi
end;
Aufruf z.B.:

Delphi-Quelltext
1:
CountCharOccurrences('e''Ein kleiner Test');                    
Das würde dann 3 ergeben.

// EDIT:
Änderungsvorschläge von user profile iconBenBE eingebracht.


ffgorcky - Di 05.05.09 11:33

Also ich hätte es ja auf die herkömmliche Art gemacht, also so wie es auch in Thema 91942 [http://www.delphi-forum.de/viewtopic.php?t=91942&start=0&postorder=asc&highlight=copy+string] im 2. Post gemacht wurde.
- Oder geht es so schneller?

Und wie kann man das erste (also das große E) auf Deine Art auch schon gleich mitzählen?


jaenicke - Di 05.05.09 12:34

user profile iconffgorcky hat folgendes geschrieben Zum zitierten Posting springen:
- Oder geht es so schneller?
Je länger der durchsuchte String ist, desto deutlicher wird der Geschwindigkeitsvorteil. Dafür kann man nur einzelne Buchstaben suchen. ;-)

user profile iconffgorcky hat folgendes geschrieben Zum zitierten Posting springen:
Und wie kann man das erste (also das große E) auf Deine Art auch schon gleich mitzählen?
Den zweiten Parameter mit dem Text mit LowerCase behandeln vor der Übergabe.