![]() |
Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Ich hätte mal ne frage gibt es vielleicht in Delphi eine Funktion die man benutzen könnte um eine Zeichenkette zu Prüfen ohne sie umzuwandeln? und ohne das man jedes Zeichen einzeln durchsucht also mit einer Schleife?
"+242423423492849028042840928403284204832948204820 93482309483209480948903284098329084203823948092482 03" aber nicht: "-2734832748327482742374827482342842384724927498723ABA237428742837493274832749274987348723847294728372" wegen den Zeichen dazwischen. Dachte vielleicht geht das mit "in" also sprich if s in ['0'..'9'] aber das würde ja nur kucken ob die drin sind aber nich ob die aneinander hängen würden. Und ich weiß nicht wie ich alle Zeichen ausser 0..9 angeben könnnte. Weil ich brauch eine Funktion die auch bei großen Zeichenketten erkennt ob es eine gültige Zahl ist ohne das ich gleich jedes Zeichen einzeln durchsuchen. Wenns nich anders geht unterteile ich den String in mehrere Teile wo noch die Umwandlung in eine Extendet Zahl funktionieren würde sprich 20 stellen oder wieviel die fassen tut. Wäre dann zwar nicht Optimal aber noch in Ordnung. thx schonmal im vorraus |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Ja hallo ersmal und Willkommen und so :hi:
also in Delphi selber is nichts vorhanden, aber wieso willst due denn nicht Stück für Stück prüfen? Bsp:
Delphi-Quellcode:
PS: IN arbeitet nicht mit ganzen String, sondern nur mit ordinalen Typem wie z.B. einem einzelnem Zeichen(Char).
B := True;
For i := 1 to Length(S) do If not ((S[i] in ['0'..'9']) or ((i = 1) and (S[i] in ['+', '-']))) Then B := False; If B Then {istZahl} Alternativ könntes du natürlich auch nach etwas suchen, welches mit "großen" Zahlen zurechtkommen. ![]() |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
naja es geht eher darum das die zahl auch z.b 2^100 stellen haben könnte also unendlich lang sein kann da jedesmal alles durchgehen is fu find ich.... das schluckt doch bissel an der performance.
|
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Hallo,
Zitat:
Gruß Hawkeye |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Unendlich lang geht nicht (irgendwann geht dir der RAM für den String aus, wo dann ab 2^30 realistisch langsam Schluß ist :zwinker: )
Und wie sollte denn sonst geprüft werden? (selbst wenn es eine Funktion dafür gäbe, dann würde die ähnlich arbeiten) Zitat:
|
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Zitat:
Einfach mal die Zeit messen, die das Verfahren benötigt, um eine -sagen wir- Zahl mit 100.000.000 Stellen zu prüfen. Wobei der Algo von himitsu noch nicht mal sonderlich performant ist, aber darum gings ihm hier sowieso nicht, nur um eine kurze und knappe Geschichte. |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
@alzaimar: OK, ein biss PChar, statt s[...], oder gleich 'ne nette ASM-Lösung, aber es ist schon mit Sicherheit viele tausend Mal schneller als z.B. 'ne Copy-StrToFloatDef-Variante :angel:
|
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Zitat:
Deshalb bin ich auch von Delphi.Win32 auf Delphi.DTM für Deterministische Turing Maschinen umgestiegen, macht die Sache gleich viel angenehmer :mrgreen: [/Etwas OT] |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Ok,
abgesehen von dem Speicherproblem :zwinker: mal ein Loesungsvorschlag. hier sei ein Hoch auf die "Definitoere" der ASCII-Konvention. Tja, die Jungs haben sich noch was gedacht. Ich definere einfach mal, dass (wie in deinem Beispiel) in dem "Zahlenstring" NUR ZIFFERN UND BUCHSTABEN aber keine Sonderzeichen Vorkommen (<30h); + und - werden ignoriert, da als Vorzeichen immer an erster Position.;
Delphi-Quellcode:
Damals war halt Rechenzeit knapp und Bit- & Boolesche-Operationen sind immer am schnellsten.
// ADA. Quellcode-Tag zwecks Leerzeichenformatierung //
______Bit_76543210 |||||||| 0 = 30h = 00110000b 1 = 31h = 00110001b . . 9 = 39h = 00111001b @ = 40h = 01000000b A = 41h = 01000001b . . ' = 60h = 01100000b a = 61h = 01100001b . . usw.. Man richte jetzt sein Augenmerk auf Bit 6. Zahlen: Bit 6 = 0; Buchstaben: Bit 6 = 1; Grossbuchstben: Bit 5 = 0; Kleinbuchstaben Bit 5 = 1; Du must also nicht deinen ganzen String duchlaufen. Definiere eine Bitmaske.
Delphi-Quellcode:
Und & Vergleichsoperationen:
function NumStr(s:String):Boolean;
var i,l : Integer; const mask = $40; // = 01000000b begin result := true; i := 1; l := Length(s)+1; while (result and (i<l)) do begin result := (mask and ORD(s[i]))<mask; inc(i); end; end; Im besten Fall n=2 , im schlimmsten fall n=Length(s)*2 Operationen. |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Zitat:
das reicht so natürlich noch nicht - Nebenbedingungen sind z.B. dass + und - nur am Anfang auftreten dürfen und dass der String nur 1 Dezimalpunkt enthalten darf, von Exponentialdarstellungen mal abgesehen. Man muss sich also eine Zustandsmaschine schreiben, der man Zeichen für Zeichen übergibt. Gruss Reinhard |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Zitat:
|
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Danke erstmal für die Vorschläge!!
Prinzipell gings nur darum das ich nich alles durchgehen wollt. Grund ist das die Daten für die Verarbeitung korrekt vorliegen müssen sprich eine durchgängige Zahl ohne Buchstaben Sonderzeichen etc. dazwischen. Ich könnte den Fehlerabfanng auch in die Verarbeitung mit reinbringen das nich das ding. Dachte nur vielleicht gibts da ne andere möglichkeit weil wäre schicker wenns vorher geschieht und er nich bei der verarbeitung merkt das es an vorletzter Stelle jetzt dann noch falsch ist. Dann hätte man sich ja die vorherigen Rechnungen sparen könnnen. Naja und das mit 2^100 war wohl bissel übertrieben gesagt aber ich meinte das auch nur darauf bezogen das die Zahlen die normalen Zahlen Integer etc. sprängen würden ich kenn jetzt BigMath nich was da oben mal gennant wurde link ging da auch nicht. Müste ich jetzt mal googeln. |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Zitat:
dein Ansatz bedeutet, alle korrekten Zahlen werden komplett 2 x gelesen, nur die unkorrekten nur einmal. Wenn du nicht gerade davon ausgehst, dass die Mehrzahl fehlerhaft ist, bringt das keinen Vorteil, sondern dauert länger. Gruss Reinhard |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
@Der_Unwissende: LOGISCH! :zwinker: :roll:
|
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Zitat:
Außerdem kann der Nullterminierte String nicht maximal 2^32 (bzw. erst bei 64 Bit 2^64) sein? @Kenshin4455 Auch wenn es ein IN gäbe, glaubst du Delphi würde das per Gedankenlesen rausfinden? Es wäre dann intern ohne eigene Routine, aber eine Überprüfung würde es trotzdem geben. Und bei 4 GB wären das paar Minuten. |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
@LoCrux:
es stimmt schon das wenn Bit 6 nicht gesetzt ist daß es eine Zahl sein könnte, aber es muß dennoch keine Zahl sein (ih weiße da nur mal auf die ganzen Steuerzeichen #0..#31 hin), also einfach nur Bit 6 zu Prüfen reicht nicht aus. @Reinhard Kern: Zitat:
@Popov: hast schon Recht (es funktioniert zwar, aber wenn die 2 Assembleranweisungen je durchgang für i=1 gesparrt würde, dann wär's schon etwas optimaler) Und es wäre bestimmt nicht schlecht, wenn bei Auffinden eines unzuläßigen Zeichens die Schleife abgebrochen (siehe Break) würde :roll:
Delphi-Quellcode:
ein Punkt war zwar nicht mit in der "Aufgabenstellung" zu erkennen, aber was soll's:
B := (S <> '') and (S[1] in ['+', '-', '0'..'9']);
For i := 2 to Length(S) do If not (S[i] in ['0'..'9']) Then Begin B := False; Break; End; If B Then {istZahl}
Delphi-Quellcode:
oder
B := (S <> '') and (S[1] in ['+', '-', '0'..'9']);
B2 := True; For i := 2 to Length(S) do If not (S[i] in ['0'..'9']) Then If B2 and (S[i] = '.') and (i < Length(S) and (S[i - 1] in ['0'..'9']) and (S[i + 1] in ['0'..'9']) Then B2 := False Else Begin B := False; Break; End; If B Then {istZahl}
Delphi-Quellcode:
oder das vorherigge nochmal mit PChar
B := (S <> '') and (S[1] in ['+', '-', '0'..'9']);
B2 := True; For i := 2 to Length(S) do If not (S[i] in ['0'..'9']) Then If B2 and (S[i] = '.') and (i < Length(S)) and ((i > 2) or (S[1] in ['0'..'9'])) Then B2 := False Else Begin B := False; Break; End; If B Then {istZahl}
Delphi-Quellcode:
(ich hoffe letzteres stimmt ... hab's jetzt nur aus'm Kopf umgeschrieben und nicht getestet)
Var P: PChar;
i, i2: Integer; B, B2: Boolean; i2 := Length(S); P := PChar(S); B := (i2 <> 0) and (P^ in ['+', '-', '0'..'9']); B2 := True; For i := 2 to i2 do Begin Inc(P); If not (P^ in ['0'..'9']) Then If B2 and (P^ = '.') and (i < i2) and ((i > 2) or (S[1] in ['0'..'9'])) Then B2 := False Else Begin B := False; Break; End; End; If B Then {istZahl} und hier nochmal die PChar-Variante ohne Punkt:
Delphi-Quellcode:
Var P: PChar;
i, i2: Integer; B, B2: Boolean; i2 := Length(S); P := PChar(S); B := (i2 <> 0) and (P^ in ['+', '-', '0'..'9']); For i := 2 to i2 do Begin Inc(P); If not (P^ in ['0'..'9']) Then Begin B := False; Break; End; End; If B Then {istZahl} |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
So wäre es mit einem Automaten (Es erkennt die Floatingpoint Notation, Fixed Point und Integer mit beliebig vielen Vorzeichen), also z.B.:
"+-+-+12345,3456453345345E-9123123123"
Delphi-Quellcode:
Function IsAnyNumber(Const aValue: String): Boolean;
Const map: Array[0..5, 1..6] Of Integer = ( {0}(1, 2, -1, 0, -1, -1), {1}(1, 2, 4, -1, -1, 9), {2}(3, -1, -1, -1, -1, 9), {3}(3, -1, 4, 0, -1, 9), {4}(5, -1, -1, 4, -1, -1), {5}(5, -1, -1, -1, -1, 9) ); Var State, cChar, i: Integer; Begin State := 0; Result := False; For i := 1 To Length(aValue) Do Begin Case aValue[i] Of '0'..'9': cChar := 1; ',', '.': cChar := 2; 'E', 'e': cChar := 3; '-', '+': cChar := 4; Else cChar := 5; End; State := map[State, cChar]; If State = -1 Then Exit; End; If State <> 9 Then State := map[State, 6]; // Zustand bei Erkennen des Terminalsymbols Result := (State = 9) End; |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Zitat:
Ansonsten ok. |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Popov, die Funktion erkennt auch Ganzzahlen, eben alle Zahlen. Äh.. oder... eh.. :gruebel: Jedenfalls hat sie das eben noch.
|
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
@himitsu
Zitat:
Zitat:
Coole Function. :cheers: :hello: |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Na, dann will ich auch noch mal was beisteuern.
Dürfte um ca. 25 % schneller sein als optimale Pascal-Lösungen Als gültig werden Strings erkannt, die a) nur Ziffern enthalten, aber mindestens eine Ziffer b) als erstes Zeichen ein Vorzeichen haben, dem mindestens eine Ziffer folgt
Delphi-Quellcode:
[edit=MrSpock]3. ASM Befehl auf Wunsch des Erstellers geändert. Mfg, MrSpock[/edit]
FUNCTION IsSignedInteger(s:string):boolean;
asm test eax,eax je @Exit // s=NIL cmp [eax-4],0 // geändert auf Wunsch des Erstellers je @Fail // s hat Länge 0 mov edx,eax mov ax,[edx] // AL=erstes Zeichen, AH=zweites Zeichen add edx,2 cmp al,'-' je @HasSign cmp al,'+' jne @NoSign @HasSign: add ah,$D0 sub ah,$0A jb @Loop // Nach Sign folgt Ziffer @Fail: xor eax,eax // Fehler jmp @Exit @NoSign: add al,$D0 sub al,$0A jae @Fail // erstes Zeichen nicht '0'..'9','-','+' jmp @Entry @Loop: mov ax,[edx] add edx,2 add al,$D0 sub al,$0A jae @CheckEnd // nicht '0'..'9' @Entry: add ah,$D0 sub ah,$0A jb @Loop // ist '0'..'9' sub ah,$D0-$0A je @True // Ist 0 Byte (Ende vom String) @CheckEnd: sub al,$D0-$0A @True: sete al @Exit: end; |
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
@LoCrux: OK, wenn wirklich nur Zahlen und Buchstaben drin sind, dann sag ich nichts dagegen :angel:
|
Re: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
@Amateurprofi:
SPEEDFREAK :chat: :bouncing4: :bounce1: :bounce2: :bouncing4: :bounce1: :bounce2: :bouncing4: :bounce1: :bounce2: :bouncing4: :bounce1: :bounce2: |
AW: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Und wie kann man testen ob ein String eine Zahl darstellt, wenn jene Zahlen auch negativ (mit vorangestelltem Minus) sein können und vom Typ Integer oder Real sein können (also mit Kommastellen, wobei das Komma je nach Land durch ein Komma oder einen Punkt dargestellt sein kann)? Gleichzeitig will ich aber Strings wie die nachfolgenden "Un"-Zahlen ausschließen:
- "12-3" - "123-" - "123." - "1.2.3" - "1-2-3" - "-.-" Bei meinem Problem kann ich mit Schleifen arbeiten. Nur der Algorithmus fällt mir nicht ein. |
AW: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
Das Einfachste:
![]() ![]() ![]() ![]() Ansonsten einfach alles nacheinander prüfen und schauen, ob was Richtiges/Falsches drin vorkommt.
Delphi-Quellcode:
Das läßt sich natürlich noch ein bissl hübscher zusammenfassen.
Result := False;
i := 1; if (i <= Length(S)) and (S[i] in ['+', '-']) then Inc(i); if (i > Length(S)) or not (S[i] in ['0'..'9']) then Exit; while (i <= Length(S)) and (S[i] in ['0'..'9']) do Inc(i); if (i <= Length(S)) and (S[i] = DecimalSeparator) then begin Inc(i); if (i > Length(S)) or not (S[i] in ['0'..'9']) then Exit; while (i <= Length(S)) and (S[i] in ['0'..'9']) do Inc(i); end; Result := i > Length(S); |
AW: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
|
AW: Zeichenkette Prüfen ob gültige Zahl ohne Umwandeln?
@himitsu & alle anderen:
Das Post von SvenLittkowski wurde von ihm auch in einem eigenen Thread gepostet, der unter dem Namen ![]() PS: Ach DeddyH ...... :p |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:56 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-2025 by Thomas Breitkreuz