AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

StringReplace und doppelte Zeichen

Ein Thema von Opa · begonnen am 23. Dez 2007 · letzter Beitrag vom 4. Mai 2009
Antwort Antwort
Seite 5 von 5   « Erste     345
alzaimar
(Moderator)

Registriert seit: 6. Mai 2005
Ort: Berlin
4.956 Beiträge
 
Delphi 2007 Enterprise
 
#41

Re: StringReplace und doppelte Zeichen

  Alt 25. Dez 2007, 14:19
So, jetzt hab ich mal ein alternatives Testszenario erstellt.

Test #1:
Ein langer String (Länge einstellbar) wird mit zufälligen Großbuchstaben gefüllt. Dann wird die Routine nacheinander für alle Buchstaben aufgerufen. Die gesamte Ausführungszeit wird gemessen und das Ergebnis dargestellt.

Test #2:
Das '_' Zeichen wird zufällig (Häufigkeit einstellbar) in einen String aus Buchstaben eingefügt. Dann wird die Routine mit '_' als zu eliminierendes Zeichen aufgerufen.

Bei den einzelnen Versionen wurden dabei einige kleine Fehler entdeckt und ausgebaut.

Dann habe ich Hawkeyes Version nochmal aufgemotzt und das ist dann in diesen Tests die schnellste Version. Hawkeyes Original ist sowieso schneller als alle anderen...
Angehängte Dateien
Dateityp: zip testfunc_120.zip (247,8 KB, 17x aufgerufen)
"Wenn ist das Nunstruck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput!"
(Monty Python "Joke Warefare")
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.366 Beiträge
 
Delphi 10.4 Sydney
 
#42

Re: StringReplace und doppelte Zeichen

  Alt 25. Dez 2007, 19:24
hab bei mir mal ein/zwei Fehlerchen behoben
Delphi-Quellcode:
Function ReduceMultiples(Const S: String; C: Char): String;
  Var Pi, Po, Pe: PChar;
    Cm: Char;

  Begin
    Result := S;
    If Result = 'Then Exit;
    Pi := @Result[1];
    Pe := Pi + Length(Result);
    Inc(Pi);
    Po := Pi;
    Cm := Result[1];
    While Pi < Pe do Begin
      If (Pi^ <> Cm) or (Pi^ <> C) Then Begin
        Inc(Po);
        Cm := Pi^;
      End;
      Inc(Pi);
      Po^ := Pi^;
    End;
    SetLength(Result, Po - @Result[1]);
  End;
und leider hab'sch festgestellt, daß mein Compiler besser optimiert, als ich ;(
Delphi-Quellcode:
Function ReduceMultiplesA(Const S: String; C: Char): String;
  Var i: Integer;

  Begin
    Result := S;
    UniqueString(Result);
    ASM
      PUSH EDI
      PUSH ESI
      MOV &i, 0
      MOV DL, &C
      MOV EAX, &Result
      MOV EAX, [EAX]
      CMP EAX, 0 // If Result_EAX = '' Then Exit;
      JZ @Exit //
      MOV ESI, EAX // Pi_ESI := @Result_EAX[1];
      MOV ECX, ESI // Pe_ECX := Pi_ESI + Length(Result_EAX);
      ADD ECX, DWORD PTR [EAX - 4] //
      INC ESI // Inc(Pi_ESI);
      MOV EDI, ESI // Po_EDI := Pi_ESI;
      MOV DH, BYTE PTR [EAX] // Cm_DH := Result_EAX[1];
      @Loop: // While Pi_ESI < Pe_ECX do Begin
      CMP ESI, ECX //
      JGE @LoopEnd //
      MOV AL, BYTE PTR [ESI] // If (Pi_ESI^ <> Cm_DH) or (Pi_ESI^ <> C_DL) Then Begin
      CMP AL, DH //
      JNZ @BeginIf //
      CMP AL, DL //
      JZ @EndIf //
      @BeginIf: //
      INC EDI // Inc(Po_EDI);
      MOV DH, BYTE PTR [ESI] // Cm_DH := Pi_ESI^;
      @EndIf: // End;
      INC ESI // Inc(Pi_ESI);
      MOV AL, BYTE PTR [ESI] // Po_EDI^ := Pi_ESI^;
      MOV BYTE PTR [EDI], AL //
      JMP @Loop // End;
      @LoopEnd: //
      MOV EAX, &Result
      SUB EDI, [EAX] // i := Po_EDI - @Result_EAX[1];
      MOV &i, EDI //
      @Exit:
      POP ESI
      POP EDI
    End;
    SetLength(Result, i);
  End;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Benutzerbild von Opa
Opa

Registriert seit: 12. Jun 2003
107 Beiträge
 
Delphi 7 Enterprise
 
#43

Re: StringReplace und doppelte Zeichen

  Alt 25. Dez 2007, 20:07
Wenn dann ist die Assembler Routine nur minimal schneller.

Als ich das mein (Ding) war nur ein dussliges Abfallprodukt, nach dem Motto schreib mal was rein ins Forum. Konnte ich nicht ahnen das dieses Tun eine solche Reaktion auslöst. Erst hatte ich dachte man macht mich hier nur dumm an.

Lob also allen die sich die Mühe gemacht haben, meinen Gedanken zu optimieren. Und ich habe sogar was gelehrt. SetLength ist mir zwar bekannt gewesen. Das dieser Befehl eine solche Auswirkung hat, was Geschwindigkeit angeht, hatte ich nicht geahnt. Normalerweise mache ich mir darüber auch keine Gedanken mehr. Alles was unterhalb einer Sek. ist, nehme ich kaum zur Kenntnis (früher war das anders, langsamer Rechner).

Ich muss sagen bin positiv überrascht, es wird nicht nur gemäkelt, ist werden auch Verbesserungsvorschläge gemacht. Lob, Lob, Lob all denen usw.
MFG

Ps.: Alter Mann ist immer am langsamten. Aber das so ein Ding nicht in Delphi ist nervt

Noch was zum optimieren Das ist (ein Test) blah , in Klammern muss weg
Code:
function _DeleteTextInKlammer(const S:string;Auf,Zu:Char):string;overload;
var
  I,P : integer;
  OK : boolean;
begin
  SetLength(Result, Length(S));
  P :=1;
  I :=1;
  OK := false;
  repeat
    if S[I] = Auf then
    begin
      OK := false;
      while (S[I] <> Zu) and (I< Length(S)) do
      inc(I);
    end;
    if S[I] =Zu
    then Ok := true
    else begin
           if I <= Length(S) then
           begin
             Result[P] := S[I];
             inc(P);
           end;
         end;
    inc(I);
  until I > Length(S);
  if not OK
  then Result := S
  else SetLength(Result,P-1);
end;
Wenn man nicht weiß was man sucht, findet man auch mit Google nichts.
Bevor ich hier eine Frage stelle, wurde Google vorher befragt. Hinweise dieser Art kann man sich schenken. Im übrigen muss mir niemand antworten.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.366 Beiträge
 
Delphi 10.4 Sydney
 
#44

Re: StringReplace und doppelte Zeichen

  Alt 25. Dez 2007, 20:22
nja, wenn jemand die Überschrift in irgendwas mit Optimieren umbenennt, dann könnten wir mit Klammern weitermachen, aber so past's nicht so ganz zum Thema

im Anhang:
Ratio umgekehrt (so sehn die Zahlen doch netter aus? ... Dauer im Vergleich zum Original)
und es wird angezeigt ob das Testergebnis richtig (OK) ist.
Angehängte Dateien
Dateityp: pas fmtestfunc_714.pas (12,5 KB, 10x aufgerufen)
Dateityp: exe testfunc_380.exe (188,5 KB, 9x aufgerufen)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Benutzerbild von Opa
Opa

Registriert seit: 12. Jun 2003
107 Beiträge
 
Delphi 7 Enterprise
 
#45

Re: StringReplace und doppelte Zeichen

  Alt 25. Dez 2007, 22:38
War auch nur gedacht, wenn einer über Wein8 keine arbeit hat.
Wenn man nicht weiß was man sucht, findet man auch mit Google nichts.
Bevor ich hier eine Frage stelle, wurde Google vorher befragt. Hinweise dieser Art kann man sich schenken. Im übrigen muss mir niemand antworten.
  Mit Zitat antworten Zitat
Dipl Phys Ernst Winter

Registriert seit: 14. Apr 2009
Ort: Jena
103 Beiträge
 
Delphi 3 Professional
 
#46

Re: StringReplace und doppelte Zeichen

  Alt 3. Mai 2009, 18:23
"Uropa" antwortet "Opa"

Halte Dich doch an das, was Du bewerkstelligen willst: Du willst Zeichen aus einem String löschen.

Delphi-Quellcode:
function TForm1.KillDoppelteZeichen(s: string): string;
var
  i: integer;
begin
  i:= 1;
  repeat
    if s[i+1]=s[i] then begin // Doppeltes Zeichen
      Delete(s, i+1, 1); continue end // entfernen
    else Inc(i); // sonst weiter
  until i=Length(s)-1;
  Result:= s
end;
Oh, da habe ich doch glatt übersehen, dass Du nur die Doppelten eines bestimmten Buchstaben eliminieren willst. Also:

Delphi-Quellcode:
function TForm1.KillDoppelteZeichen(s: string; ch:Char): string;
var
  i: integer;
begin
  i:= 1;
  repeat
    if (s[i]=ch) and (s[i+1]=s[i]) then begin Delete(s, i+1, 1); continue end
    else Inc(i);
  until i=Length(s)-1;
  Result:= s
end;
Da das alles im Augenblick geht, ist die Geschwindigkeit kein Thema. Oder willst di im String die ganzen Budenbroks übergeben.
Angehängte Dateien
Dateityp: exe killdoppeltezeichen_107.exe (140,1 KB, 5x aufgerufen)
Dateityp: exe killdoppeltezeichen1_692.exe (141,0 KB, 4x aufgerufen)
Autor: DP Ernst Winter
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#47

Re: StringReplace und doppelte Zeichen

  Alt 3. Mai 2009, 18:55
Mal davon abgesehen, dass der Thread jetzt schon über ein Jahr alt ist läuft dein Algorithmus in quadratischer Zeit, wo nur lineare Zeit nötig wäre. Das funktioniert zwar, wird aber niemanden überzeugen.
  Mit Zitat antworten Zitat
Dipl Phys Ernst Winter

Registriert seit: 14. Apr 2009
Ort: Jena
103 Beiträge
 
Delphi 3 Professional
 
#48

Re: StringReplace und doppelte Zeichen

  Alt 4. Mai 2009, 11:02
function KillDoppelZeichenToZeichen(S:string;C:Char):string ;

Nachdem ich diese kriegerische Funktion in meine Beispielsammlung aufgenommen hatte, kam die Frage
wozu sie nütze ist.

Die Beispiele mit C=x erscheinen mir sinnlos, einzig C=Leerzeichen macht einen Sinn, dann sollten wir aber glech

function DeleteDouleSpace(s: string): string;

entwickeln, die führende und doppelte Leerzeichen entfernt.

Delphi-Quellcode:
function TForm1.DeleteDoubleSpace(s: string): string;
var
  i: integer;
begin
  if Length(s)<2 then begin Result:= ''; Exit end;
  i:= 1;
  repeat
    if (s[i]=' ') and (s[i+1]=s[i]) then begin Delete(s, i+1, 1); continue end
    else Inc(i);
  until i=Length(s);
  Result:= s
end;
Die Geschwindigkeit scheint mir kein Thema zu sein, da das im Augenglick ausgeführt wird.

Exception bei zu kurzem String abgefangen
Autor: DP Ernst Winter
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
38.366 Beiträge
 
Delphi 10.4 Sydney
 
#49

Re: StringReplace und doppelte Zeichen

  Alt 4. Mai 2009, 11:28
völlig unoptimiert, aber zumindestens ohne "unübersichtlierem" Continue-rumgespringe
Delphi-Quellcode:
Result := S;
i := Length(Result) - 1;
While i > 0 do Begin
  If (Result[i] = ' ') and (Result[i + 1] = ' ') Then Delete(Result, i + 1, 1);
  Dec(i);
End;
steht so in etwa in meinem TXMLFile.Trim ... nja, erst die Funktion, dann alles Durchoptimieren

aber wie gesagt, diese ständigen Zugriffe auf die Chars im String (da wird mehr gemacht, als nur das Zeichen ausgelesen) und das zu häufige Rumkopieren des gesamten Strings, bei jedem Delete .... nicht unbedingt Schnell und Resourcenschonend.

[add]
Code:
function TForm1.DeleteDoubleSpace([b]s: string[/b]): string;
und was den Funktionsaufruf angeht ... siehe http://www.delphipraxis.net/internal...t.php?t=156940

[add2]
ach ja, gib mal bitte deiner Funktion einen Leerstring zum Futtern DeleteDoubleSpace('') ...
die Exception ist bestimmt ganz hübsch Anzusehn
und bei eingeschalteter Bereichsprüfung würde auch schon ein String mit weniger als 2 Zeichen eine Meldung von sich geben.

MfG
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
Delphi-Tage 2005-2014
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +2. Es ist jetzt 17:51 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf