![]() |
Effizienteste Datenverarbeitung eines Strings
Hallo zusammen
Ich habe folgende String struktur: <G48.51123,9.71545;G48.51123,9.71545;G48.51123,9.7 1545;G48.51123,9.71545;> Natürlich um einiges länger... Nun möchte ich nur die Nummern daraus erhalten also 48.51123 9.71545 . . . Wie mache ich dies am effizientesten? < und > signalisieren einen start und ein ende ein G signalisiert den beginn eines zweier blocks ein ; signalisiert das ende eines zweier blockes Danke schonmal |
AW: Effizienteste Datenverarbeitung eines Strings
Am effizientesten?
Code:
Das ist aber nicht wirklich am effizientesten, aber dafür am einfachsten zu implementieren. Optimal geht das eigentlich nur mit einer Schleife und ein wenig Fallunterscheidung.
start = 1;
wiederhole posG = Pos('G', Start); Verlasse die Schleife, wenn posG = 0; posKomma = Pos(',') ab PosG; Zahl1 = TextZwischen(posG + 1, posKomma - 1); posSemikolon =Pos(';') ab PosKomma; Zahl2 = TextZwischen(posSemikolon + 1, posKomma2 - 1); Start = posSemikolon + 1 |
AW: Effizienteste Datenverarbeitung eines Strings
Ich würde da den sledgehammer rausholen und mit Regulären Ausdrücken arbeiten.
|
AW: Effizienteste Datenverarbeitung eines Strings
stümmt.
|
AW: Effizienteste Datenverarbeitung eines Strings
Was verstehst du unter Effizient?
- einfach - einfach + etwas schneller - noch schneller (nicht so einfach) |
AW: Effizienteste Datenverarbeitung eines Strings
Danke für eure antworten...
Zitat:
es sei den etwas schneller ist zu langsam :) Es handelt sich um bis zu 128000 Zeichen Kannst du ein paar beispiele machen oder suchworte liefern? Danke :) Zitat:
|
AW: Effizienteste Datenverarbeitung eines Strings
Ungewünschte Zeichen herausfiltern geht auch mit stringReplace.
Delphi-Quellcode:
begin deinString := stringReplace(deinString, '<', '', [rfReplaceAll]); deinString := stringReplace(deinString, '>', '', [rfReplaceAll]); deinString := stringReplace(deinString, 'G', '', [rfReplaceAll]); deinString := stringReplace(deinString, ';', #13+#10, [rfReplaceAll]); deinString := stringReplace(deinString, ',', #13+#10, [rfReplaceAll]); end; |
AW: Effizienteste Datenverarbeitung eines Strings
Zitat:
Das dürfte wohl das schnellste sein :) Danke! :) |
AW: Effizienteste Datenverarbeitung eines Strings
StringReplace ist eher sehr langsam ... je länger der String und um so mehr Ersetzungen, um so langsamer wird es.
Aber wenn schon, dann könnte man ";G" in ein "," tauschen, dann noch "<G" und ">" entfernen ( ![]() Ansonsten würde ich es noch mit PosEx und Copy versuchen. |
AW: Effizienteste Datenverarbeitung eines Strings
das meine ich könnte relativ flott sein ....
eine Bremse könnte SetLength(a,High(a)+2); sein, hier gegf. einfach in größeren Blöcken anfordern und eine Zähler mitlaufen lassen ...
Delphi-Quellcode:
mit
TPointF=Record
x:Double; y:Double; End; TPointArray=Array of TPointF;
Delphi-Quellcode:
Procedure FillArray(var a:TPointarray;Const s:AnsiString);
var s1,s2:AnsiString; i,l,x1,x2:Integer; isFirst:Boolean; begin s1 := StringOfChar(#0,10); s2 := StringOfChar(#0,10); x1 := 0; x2 := 0; i := 1; l := Length(s); while i<l do begin if s[i] = 'G' then begin x1 := 0; isFirst := true end else if s[i] = ',' then begin x2 := 0; isFirst := false; inc(x1); s1[x1] := #0; end else if s[i] = ';' then begin x1 := 0; inc(x2); s2[x2] := #0; SetLength(a,High(a)+2); a[High(a)].X := StrToFloat(s1); a[High(a)].Y := StrToFloat(s2); end else if s[i] = '.' then begin if isFirst then begin inc(x1); s1[x1] := AnsiChar(Decimalseparator); end else begin inc(x2); s2[x2] := AnsiChar(Decimalseparator); end; end else if s[i] in ['0'..'9'] then begin if isFirst then begin inc(x1); s1[x1] := s[i]; end else begin inc(x2); s2[x2] := s[i]; end; end; inc(i); end; end; |
AW: Effizienteste Datenverarbeitung eines Strings
Falls der String immer genau so aufgebaut ist,
also mit einem Buchstaben beim ersten Wert und mit abschließenden ";", dann ginge auch Folgendes "<" + "Gxxxx,yyyy;" + "Gxxxx,yyyy;" + ... + ">"
Delphi-Quellcode:
Statt dem Zwischenspeichern, in der StringListe, könnte man die beiden Zahlen auch direkt verarbeiten, am Ende der Schleife.
var
S: String; L: TStringList/TStrings; i, i2: Integer; S := '<G48.51123,9.71545;G48.51123,9.71545;G48.51123,9.71545;G48.51123,9.71545;>'; L.Clear; i := 1; while True do begin i2 := PosEx(',', S, i); if i2 = 0 then Break; L.Add(Copy(S, i + 2, i2 - i - 2)); i := PosEx(';', S, i2); if i = 0 then Break; L.Add(Copy(S, i2 + 1, i - i2 - 1)); end; |
AW: Effizienteste Datenverarbeitung eines Strings
Vielleicht auch ein Ansatz, wenn deine Terminus 'Einfachheit' bedeutet, daß du auf möglichst wenig fertige Funktionen (Pos, PosEx, etc.) verzichten willst:
![]() Nicht der optimalste und hübscheste Code, sollte aber für deine Geschichten funzen. Jan |
AW: Effizienteste Datenverarbeitung eines Strings
Zitat:
|
AW: Effizienteste Datenverarbeitung eines Strings
Oh, das sah da irgendwie anders aus, hatte mir den Code nicht komplett angesehn.
Pos sah nicht wie PosEx aus (waren ja nur zwei Parameter) und ich hate am Ende einfach (ohne hinzgucken) irgendwo ein Delete erwartet :oops: Nja, k.A. ob eine RegEx-Prüfung (da sie ja mehr prüfen muß) doch schneller ist ... zumindestens nicht, wenn das RegEx in Delphi geschrieben wäre X'D Hey, dann war ja gleich der erste Vorschlag so mit das Schnellste, was man wohl mit delphieigenen Mitteln so hinbekommen können würde:thumb: |
AW: Effizienteste Datenverarbeitung eines Strings
Zitat:
Delphi-Quellcode:
Es wird aber nicht auf die kleiner/größer Zeichen geachtet. Zumal die Zeichenfolge mit diesen Zeichen öffter vorkommen kann
L.Add(Copy(S, i + 2, i2 - i - 2));
|
AW: Effizienteste Datenverarbeitung eines Strings
Zitat:
Auf das ---> PRÜFEN <--- wurde verzichtet. Nix 'vergessen'. hab ich nicht geschrieben und auch nicht gemeint. Klar soweit ;-)
Delphi-Quellcode:
Getippt und nicht getestet.
Procedure ProcessInputString (const s: String);
Var state : TParserStates; // stWaitForTagOpen, stWaitForGee, stEatFirstNumber stEatSecondNumber; number1, number2 : String; i : Integer; begin state := stWaitForTagOpen; number1 := ''; number2 := ''; For i:=1 to length (s) do case state of stWaitForTagOpen : if s[i] = '<' Then state := stWaitForGee else Raise EParserException.Create('"<" expected'); stWaitForGee : case s[i] of 'G' : state := stEatFirstNumber; '>' : state := stEndOfInput; else Raise EParserException.CreateF('">" or "G" expected'); end; stEatFirstNumber : if s[i] = ',' Then state := stEatSecondNumber else number1 := number1 + s[i]; stEatSecondNumber : if s[i] = ';' then begin state := stWaitForGee; ProcessNumbers (number1, number2); number1 := ''; number2 := ''; end else number2 := number2 + s[i]; end; if state <>stEndOfInput Then Raise EParserError ('Unexpected EOF'); end; Sollte eigentlich am Schnellsten sein (ok, mit PChar vielleicht noch schneller), denn es gibt nur eine Schleife und man geht nur 1x von vorne nach hinten. |
AW: Effizienteste Datenverarbeitung eines Strings
Zitat:
|
AW: Effizienteste Datenverarbeitung eines Strings
Je weniger man prüft, um so schneller geht es. (das ersparrt bestimmt nichmal 'ne halbe Millisekunde :stupid: )
|
AW: Effizienteste Datenverarbeitung eines Strings
Die Vergabe der Namen ist köstlich
Delphi-Quellcode:
.
stEatFirstNumber, stEatSecondNumber
Musste mal gesagt werden. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:50 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz