Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Byte-Suche, String-Vergleich mit A>B, A<B und A=B (https://www.delphipraxis.net/205868-byte-suche-string-vergleich-mit-b-b-und-%3Db.html)

Schucki 26. Okt 2020 08:43

Byte-Suche, String-Vergleich mit A>B, A<B und A=B
 
Hallo,

kann es sein das es Einschränkungen gibt, wenn man zwei Strings mit <, > und = vergleicht?
Ich habe mir eine Routine zur "Byte-Suche in TStringList" geschrieben, wo genau das gemacht wird.

Es werden aber nicht immer die Einträge gefunden, weil der Vergleich manchmal in die falsche Richtung verzweigt, sobald andere Zeichen in den Einträgen vorkommen als Buchstaben und Zahlen. (z.B _,!,# oder ähnlich )

Delphi-Quellcode:
// strlData.Sort = True!
procedure GetKeyStrPositionInList(strKey:string; strlData:TStringList;
                                  var intPosStart:Integer);

var intL,intR: Integer;
    bolFound: Boolean;

begin
  intL := 0;
  intR := Pred(strlData.Count);
  intPosStop := -1;
  bolFound := False;
  while (intL <= intR) and not bolFound do begin
    intPosStart := Round( (intL+intR) / 2);

    strData := UpperCase(CsvCtrl.GetStrFromColumn(0, strlData[intPosList]));
    if strKey < strData then intR := intPosStart - 1;
    if strKey > strData then intL := intPosStart + 1;
    if strKey = strData then bolFound := True;
  end;
  if not bolFound then intPosStart := -1;
end;

Olli73 26. Okt 2020 09:30

AW: Byte-Suche, String-Vergleich mit A>B, A<B und A=B
 
Versuch mal AnsiUpperCase anstatt UpperCase.

Gausi 26. Okt 2020 10:44

AW: Byte-Suche, String-Vergleich mit A>B, A<B und A=B
 
Ich hatte neulich auch Probleme mit sortierten StringListen und Zeichen wie "-". Der Punkt ist wohl, dass Funktionen wie AnsiCompareText standardmäßig etwas mehr machen als erwartet: https://entwickler-ecke.de/viewtopic.php?t=118089
U.a. werden Bindestriche bei der Sortierung damit nicht berücksichtigt.

Probier mal, deine Stringvergleiche (aktuell mit <, >, =) durch AnsiCompareText zu ersetzen. Dann sollte dein Vergleich für die binäre Suche mit dem Vergleich übereinstimmen, der für die Sortierung verwendet wird.

himitsu 26. Okt 2020 11:23

AW: Byte-Suche, String-Vergleich mit A>B, A<B und A=B
 
  • UpperCase macht nur ASCII, bzw. nur A-Z
  • AnsiUpperCase gibt es alsn ANSI und WIDE (jemand gam auf die kranke Idee, dass die Unicode-Versionen genauso heißen sollen)
    und wie AnsiCompareText oder AnsiSameText beachten die aktuellen Spracheintellungen, sowie CombiningChars (Ä wird wie A+¨ behndelt),
    auch werden je nach Sprache einige Chars anders sortiert. (im Deutschen sind z.B. A und Ä zusammen, obwohl sie Binär weiter entfernt sind)
  • WideUpperCase und WideSameText ist für den WideString und sollte besser nicht für "String" verwendet werden, da sonst die Strings unnötig in einen BSTR umkopiert werden.

Schucki 26. Okt 2020 11:45

AW: Byte-Suche, String-Vergleich mit A>B, A<B und A=B
 
Danke für alle Antworten!

Zitat:

Zitat von Gausi (Beitrag 1476106)
Probier mal, deine Stringvergleiche (aktuell mit <, >, =) durch AnsiCompareText zu ersetzen.

OK das funktioniert wirklich!
Jetzt habe ich in der Beschreibung zu AnsiCompareText gelesen das es "Länderspezifisch" ist. Dachte mir, dann nehme ich doch lieber CompareText aber das funktioniert hingegen wieder nicht!

Wie kann ich nun sicherstellen das eine auf meinem PC sortierte Liste auf ALLEN Systemen gleich sortiert bleibt und die Routine dann auf ALLEN PC's das richtige Ergebnis liefert?

Das mir so eine einfache Sache, mir solche Sorgen bereiten wird, hätte ich auch nicht erwartet. :)

Gausi 26. Okt 2020 12:28

AW: Byte-Suche, String-Vergleich mit A>B, A<B und A=B
 
Zitat:

Zitat von Schucki (Beitrag 1476109)
Wie kann ich nun sicherstellen das eine auf meinem PC sortierte Liste auf ALLEN Systemen gleich sortiert bleibt und die Routine dann auf ALLEN PC's das richtige Ergebnis liefert?

Die Sortier-Methode, die von der Stringlist intern verwendet wird, benutzt AnsiCompareText bzw. AnsiCompareString (je nachdem, ob CaseSensitive gesetzt ist oder nicht). Daher musst du mit deiner Binärsuche auch diese Vergleichsoperation nutzen.

Wenn du die Liste zur Laufzeit sortierst (und nicht z.B. aus einer Textdatei lädst und implizit annimmst, dass sie dann sortiert ist), dann sollte der Code mit AnsiCompareXXX überall funktionieren. Allerdings ist die Sortierung ggf. anders - aber davon merkst du bei der Suche nichts.

Wenn du die Sortierung länderunabhängig immer gleich haben willst, dann musst du deine eigene Sortierfunktion schreiben, bzw. eine eigene Compare-Funktion, die du dann mit CustomSort verwendest. Und diese Compare-Funktion musst du dann auch in der Binärsuche nutzen.

Schucki 26. Okt 2020 13:58

AW: Byte-Suche, String-Vergleich mit A>B, A<B und A=B
 
Vielen Dank! :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:35 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