AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Neuen Beitrag zur Code-Library hinzufügen Delphi ReverseString für ältere Delphi-Versionen
Thema durchsuchen
Ansicht
Themen-Optionen

ReverseString für ältere Delphi-Versionen

Ein Thema von Wolfgang Mix · begonnen am 11. Dez 2009 · letzter Beitrag vom 12. Dez 2009
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Wolfgang Mix
Wolfgang Mix

Registriert seit: 13. Mai 2009
Ort: Lübeck
1.222 Beiträge
 
Delphi 2005 Personal
 
#1

ReverseString für ältere Delphi-Versionen

  Alt 11. Dez 2009, 16:28
Wie aus diesem Thread http://www.delphipraxis.net/internal...109571#1109571
hervorgeht, fehlt die Funktion ReverseString in älteren Delphi-Versionen. Daher lege ich als Ersatz
meine Komposition noch einmal hier ab, damit man sie auch findet.

Delphi-Quellcode:
//Wolfgang Mix - Delphi-PRAXiS
function ReverseString (MyString: string): string;
var HelpString:string;
    i:integer;
begin
  HelpString:='';
  for i:=length(MyString) downto 1 do
  HelpString:=HelpString+MyString[i];
  result:=HelpString;
end;

//Usage
procedure TForm1.Button1Click(Sender: TObject);
var String1,String2:String;
begin
  String1:=Edit1.Text;
  String2:=ReverseString(String1);
  Edit2.Text:=String2;
end;
Gruß

Wolfgang
Wolfgang Mix
if you can't explain it simply you don't understand it well enough - A. Einstein
Mein Baby:http://www.epubli.de/shop/buch/Grund...41818516/52824
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#2

Re: ReverseString für ältere Delphi-Versionen

  Alt 11. Dez 2009, 16:39
Ich hätte da noch eine schnellere Version im Kopf:
Delphi-Quellcode:
// (c) 2009 jfheins - member of Delphi-PRAXiS
function ReverseString (str: string): string;
var
  i, len:integer;
begin
  len := length(str);
  setlength(Result, len);
  for i := len downto 1 do
    Result[i] := str[len - i + 1];
end;
Optimierungen:
1. Wegfall des Hilfsstrings
2. Statt der Verkettung von String und Char jetzt mit setlength und Zugriff per Index

Wobei ich mich (ein weiteres mal) frage, ob das nicht etwas sehr trivial ist - die Code-Library sollte ja gerade Qualität statt Quantität enthalten
  Mit Zitat antworten Zitat
Benutzerbild von Wolfgang Mix
Wolfgang Mix

Registriert seit: 13. Mai 2009
Ort: Lübeck
1.222 Beiträge
 
Delphi 2005 Personal
 
#3

Re: ReverseString für ältere Delphi-Versionen

  Alt 11. Dez 2009, 16:52
Ich gebe Dir Recht, soon Ding coden wir in 5 Minuten,
aber Anfänger haben mit noch einfacheren Dingen Schwierigkeiten.
Andererseits hat Embarcadingsbums noch trivialere Funktionen,
wenn ich da an Tommorrow und Yesterday denke

Gruß

Wolfgang
Wolfgang Mix
if you can't explain it simply you don't understand it well enough - A. Einstein
Mein Baby:http://www.epubli.de/shop/buch/Grund...41818516/52824
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

Re: ReverseString für ältere Delphi-Versionen

  Alt 11. Dez 2009, 23:08
Delphi-Quellcode:
Function ReverseString(Const Text: String): String;
Var L: Integer;
  S, D: PChar;
Begin
  L := Length(Text) - 1;
  SetLength(Result, L + 1);
  S := PChar(Text);
  D := PChar(Result) + L;
  For L := L downto 0 do Begin
    D^ := S^;
    Inc(S);
    Dec(D);
  End;
End;
Ihr wißt aber, daß die/unsere Ansi-Varianten nur mit Singelbyte-Zeichensätzen richtig arbeiten?


Und weil ich grad mal 'nen Sekündchen lang Lange Weile hatte:
Delphi-Quellcode:
Function ReverseString(Const Text: AnsiString): AnsiString; Overload;
  ASM
    PUSH EDI
    PUSH ESI
    PUSH EDX
    PUSH EAX
    XCHG EAX, EDX
    TEST EDX, EDX
    JZ @@ZeroSet
    SUB EDX, 4
    MOV EDX, [EDX]
    @@ZeroSet:
    CALL _LStrSetLength
    POP ESI
    POP EDI
    MOV EDI, [EDI]
    SUB EDI, 4
    MOV ECX, ESI
    TEST ECX, ECX
    JZ @@Exit
    SUB ECX, 4
    MOV ECX, [ECX]
    //XOR EAX, EAX
    //@@Loop:
    //MOV DL, [ESI + EAX]
    //MOV [EDI + ECX], DL
    //INC EAX
    //LOOP @@Loop
    //@@Exit:
    PUSH ECX
    MOV EAX, ECX
    AND EAX, $3
    ADD EDI, EAX
    SHR ECX, 2
    // TEST ECX, ECX // wenn SHR das Zero-Flag nicht setzt, dann dieses einfügen
    JZ @@None4
    XOR EAX, EAX
    @@Loop4:
    MOV EDX, [ESI + EAX * 4]
    BSWAP EDX
    MOV [EDI + ECX * 4], EDX
    INC EAX
    LOOP @@Loop4
    @@None4:
    POP EAX
    MOV ECX, EAX
    AND ECX, $3
    JZ @@Exit
    AND EAX, $FFFFFFFC
    @@Loop:
    MOV DL, [ESI + EAX]
    MOV [EDI + ECX + 1], DL
    INC EAX
    LOOP @@Loop
    @@Exit:
    POP ESI
    POP EDI
  End;

{$IFDEF UNICODE}
Function ReverseString(Const Text: UnicodeString): UnicodeString; Overload;
  ASM
    PUSH EDX
    PUSH EAX
    XCHG EAX, EDX
    TEST EDX, EDX
    JZ @@ZeroSet
    SUB EDX, 4
    MOV EDX, [EDX]
    @@ZeroSet:
    CALL _UStrSetLength
    POP ESI
    POP EDI
    MOV EDI, [EDI]
    SUB EDI, 2
    MOV ECX, ESI
    TEST ECX, ECX
    JZ @@Exit
    SUB ECX, 4
    MOV ECX, [ECX]
    XOR EAX, EAX
    @@Loop:
    MOV DX, [ESI + EAX * 2]
    MOV [EDI + ECX * 2], DX
    INC EAX
    LOOP @@Loop
    @@Exit:
  End;
{$ENDIF}

Function ReverseString(Const Text: WideString): WideString; Overload;
  ASM
    PUSH EDX
    PUSH EAX
    XCHG EAX, EDX
    TEST EDX, EDX
    JZ @@ZeroSet
    SUB EDX, 4
    MOV EDX, [EDX]
    SHR EDX, 1
    @@ZeroSet:
    CALL _WStrSetLength
    POP ESI
    POP EDI
    MOV EDI, [EDI]
    SUB EDI, 2
    MOV ECX, ESI
    TEST ECX, ECX
    JZ @@Exit
    SUB ECX, 4
    MOV ECX, [ECX]
    SHR ECX, 1
    XOR EAX, EAX
    @@Loop:
    MOV DX, [ESI + EAX * 2]
    MOV [EDI + ECX * 2], DX
    INC EAX
    LOOP @@Loop
    @@Exit:
  End;
Und weil ich einfach zu doof bin, um die Funktionen der System-Unit aufzurufen
(ich hasse es, daß die Namen der System.pas nicht mit der System.dcu und der CPU-Anzeige übereinstimmen)
Delphi-Quellcode:
Procedure _LStrSetLength(Var Text: AnsiString; Len: Integer);
  Begin
    SetLength(Text, Len);
  End;

{$IFDEF UNICODE}
Procedure _WStrSetLength(Var Text: WideString; Len: Integer);
  Begin
    SetLength(Text, Len);
  End;
{$ENDIF}

Procedure _UStrSetLength(Var Text: UnicodeString; Len: Integer);
  Begin
    SetLength(Text, Len);
  End;
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von Wolfgang Mix
Wolfgang Mix

Registriert seit: 13. Mai 2009
Ort: Lübeck
1.222 Beiträge
 
Delphi 2005 Personal
 
#5

Re: ReverseString für ältere Delphi-Versionen

  Alt 11. Dez 2009, 23:18
@himitsu:
Zitat:
Und weil ich einfach zu doof bin, um die Funktionen der System-Unit aufzurufen
Tröste dich, das geht mir fast immer so.
Ausserdem ist es viel spannender, die Probleme selber zu lösen.

Gruß

Wolfgang
Wolfgang Mix
if you can't explain it simply you don't understand it well enough - A. Einstein
Mein Baby:http://www.epubli.de/shop/buch/Grund...41818516/52824
  Mit Zitat antworten Zitat
Benutzerbild von Wolfgang Mix
Wolfgang Mix

Registriert seit: 13. Mai 2009
Ort: Lübeck
1.222 Beiträge
 
Delphi 2005 Personal
 
#6

Re: ReverseString für ältere Delphi-Versionen

  Alt 11. Dez 2009, 23:36
Inzwischen denke ich, dass das Thema trotz aller Simplizität doch Wert ist,
in der CodeLib untergebracht zu werden.
Wolfgang Mix
if you can't explain it simply you don't understand it well enough - A. Einstein
Mein Baby:http://www.epubli.de/shop/buch/Grund...41818516/52824
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#7

Re: ReverseString für ältere Delphi-Versionen

  Alt 11. Dez 2009, 23:37
Hi,

ich verstehe euren Programmiertechnischen Aufwand nicht.

Delphi-Quellcode:
function ReverseAnsiString(const s: Ansistring): Ansistring;
var i : integer;
begin
  for i := length(s) downto 1 do
    Result := Result + s[i];
end;
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#8

Re: ReverseString für ältere Delphi-Versionen

  Alt 12. Dez 2009, 00:12
Vielleicht, weil dein Code nicht wirklich gut arbeitet?

Und weil er über 20 Mal langamer ist, als mein Pascal-Code?
Also inkl. dem Result:=''; ansonsten bremst es je Aufruf natürlich noch extremer ab, da ja der Resultstring immer größer wird.
(der Code von jfheins ist dagegen 3 Mal schneller, bei einem 10 Zeichen langem String, wärend dein Code eine expotentiell steigende Zeit zur Stringlänge hat und unsere Codes arbeiten linear)

Dein String ist nicht initialisiert.
Delphi-Quellcode:
function ReverseAnsiString(const s: Ansistring): Ansistring;
var i : integer;
begin
  Result := '';
  for i := Length(s) downto 1 do
    Result := Result + s[i];
end;
probier es mal aus ... du wirst ganz schön erstaunt sein
Delphi-Quellcode:
var S, S2: AnsiString;
  i: Integer;

S := '123';
for i := 0 to 9 do
begin
  S2 := ReverseString(S);
  ShowMessage(S2);
end;
$2B or not $2B
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#9

Re: ReverseString für ältere Delphi-Versionen

  Alt 12. Dez 2009, 00:35
Zitat:
Dein String ist nicht initialisiert.
Muss man auch nicht. In der Function wird Result automatisch geleert.
sicherlich, guter Style ist es nicht.

Mit der Geschwindigkeit kann es schon so sein, da Setlengt den Stringzähler
" s[0] := x " (klappt ja bei Delphi nur noch per Umweg [SetLength]) den ben. Platz
gleich reserviert ohne ihn jedes mal erneut um eins zu erhöhen.

Vill. bin ich auch nur zu müde um richtig nachdenken zu können.
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#10

Re: ReverseString für ältere Delphi-Versionen

  Alt 12. Dez 2009, 00:44
Nein, beim Result ist es was Anderes, der wird nicht automatisch initialisiert, so wie es bei normalen Variablen der Fall ist.

Wie gesagt, probier es einfach mal aus.
ShowMessage zeigt nacheinander dieses an:

1. Aufruf: Result/S=321
2. Aufruf: Result/S=321321
3. Aufruf: Result/S=321321321
4. Aufruf: Result/S=321321321321
5. Aufruf: Result/S=321321321321321
6. Aufruf: Result/S=321321321321321321
7. Aufruf: Result/S=321321321321321321321
8. Aufruf: Result/S=321321321321321321321321
9. Aufruf: Result/S=321321321321321321321321321
10. Aufruf: Result/S=321321321321321321321321321321


Dieser Code:
Delphi-Quellcode:
function ReverseString(const s: Ansistring): Ansistring;
var i : integer;
begin
  for i := Length(s) downto 1 do
    Result := Result + s[i];
end;

var S, S2: AnsiString;
  i: Integer;

S := '123';
for i := 0 to 9 do
begin
  S2 := ReverseString(S);
  ShowMessage(S2);
end;
enspricht intern eigentlich diesem:
Delphi-Quellcode:
procedure ReverseString(const s: Ansistring; var Result: Ansistring);
var i : integer;
begin
  for i := Length(s) downto 1 do
    Result := Result + s[i];
end;

var S, S2: AnsiString;
  i: Integer;

S := '123';
for i := 0 to 9 do
begin
  ReverseString(S, S2);
  ShowMessage(S2);
end;
Und nun erkennt man bestimmt auch, warum es dort nicht funktioneren kann.
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 +1. Es ist jetzt 17:21 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