AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Library: Object-Pascal / Delphi-Language Delphi "Natürliche" Sortierungen von Strings
Thema durchsuchen
Ansicht
Themen-Optionen

"Natürliche" Sortierungen von Strings

Ein Thema von luwo · begonnen am 16. Sep 2004 · letzter Beitrag vom 27. Jun 2006
Antwort Antwort
Benutzerbild von luwo
luwo

Registriert seit: 8. Jan 2004
Ort: Bamberg
46 Beiträge
 
Delphi XE2 Enterprise
 
#1

"Natürliche" Sortierungen von Strings

  Alt 16. Sep 2004, 15:43
Keine Ahnung, ob dieses Problem nicht schon jemand hier im Forum angesprochen hat,
aber im Netz hab ich einfach keine (brauchbare) Lösung gefunden
und deshalb kurzerhand selbst in die Tasten gegriffen.

Zum Thema Sortierung wurde schon viel geschrieben.
Ich brauchte allerdings keinen superoptimierten Sortierungsalgorithmus,
sondern eher eine einfach Lösung die Strings der "menschlichen Ordnung" nach sortiert.
(ähnlich der natsort()-Funktion von PHP)

Zur Verdeutlichung:

a) normale ASCII-Sortierung:
rfc1.txt
rfc2086.txt
rfc822.txt

b) natürliche/menschliche Sortierung
rfc1.txt
rfc822.txt
rfc2086.txt

Hier ein Link zum Thema.

Der Code ist sicher suboptimal, aber er funzt

Delphi-Quellcode:
function Compare_NaturalSort(List: TStringList; Index1, Index2: Integer): Integer;

  function JustNumbers(instr:string):string ;
  var
    t:integer;
  begin
   for t:=1 to length(instr) do
     if instr[t] in ['0'..'9'] then result:=result+instr[t];
  end;

var
  di1, di2: Integer;
begin
  if not TryStrToInt(JustNumbers(List[Index1]), di1) then
    di1:=0;
  if not TryStrToInt(JustNumbers(List[Index2]), di2) then
    di2:=0;

  if di1<di2 then
    Result:=-1
  else if di1>di2 then
    Result := 1
  else
    Result := 0;
end;

{Anwendungsbeispiel:}

procedure NaturalSort(const Strings2Sort:TStrings) ;
var
  SL:TStringlist;
begin
  SL:=tstringlist.create;

  SL.Assign(Strings2Sort);
  SL.CustomSort(Compare_NaturalSort);
  Strings2Sort.assign(SL);

  SL.free;
end;



procedure TForm1.Button1Click(Sender: TObject);
begin
  NaturalSort(Listbox1.Items);
end;
shmia hat noch auf etwas hingewiesen:
Zitat:
Deine Compare-Funktion arbeitet IMHO nicht richtig, wenn keine Ziffern enthalten sind.
Man müsste die orginale C-Funktion ( http://sourcefrog.net/projects/natsort/strnatcmp.c ) nach
Delphi übersetzen, dann hat die Sache Hand & Fuss.
Natürlich muss auch der Disclaimer von Martin Pool dazu, sonst wär's ja unfair.
Nachtrag: H4ndy hat die C-Funktion übersetzt und ihr findet diese in diesem Thread weiter unten. MfG, Matze.



[edit=Chakotay1308]Beitrag aufgearbeitet. Mfg, Chakotay1308[/edit]
[edit=Matze]Code aktualisiert. Mfg, Matze[/edit]
[edit=Matze] Mfg, Matze[/edit]
50726F626C656D3F204F53492D53636869636874203821
  Mit Zitat antworten Zitat
CalganX

Registriert seit: 21. Jul 2002
Ort: Bonn
5.403 Beiträge
 
Turbo Delphi für Win32
 
#2

Re: "Natürliche" Sortierungen von Strings

  Alt 15. Okt 2004, 15:06
Der User djmasi hat noch eine etwas elegantere, schnellere und optimalere Alternative gebastelt:
Delphi-Quellcode:
//****************************************************************************//
function NatCompareText(const S1, S2: WideString): Integer;
begin
  SetLastError(0);
  Result := CompareStringW(LOCALE_USER_DEFAULT,
                           NORM_IGNORECASE or
                           NORM_IGNORENONSPACE or
                           NORM_IGNORESYMBOLS,
                           PWideChar(S1),
                           Length(S1),
                           PWideChar(S2),
                           Length(S2)) - 2;
  case GetLastError of
    0: ;
    ERROR_CALL_NOT_IMPLEMENTED: Result := DumbItDownFor95(S1,
                                                          S2,
                                                          NORM_IGNORECASE or
                                                          NORM_IGNORENONSPACE or
                                                          NORM_IGNORESYMBOLS);
  else
    RaiseLastOSError;
  end;
end;
//****************************************************************************//
//****************************************************************************//
Und falls es doch Probleme gibt (wurde im PSDK extra drauf hingewiesen):
Delphi-Quellcode:
function DumbItDownFor95(const S1, S2: WideString; CmpFlags: Integer): Integer;
var
  a1, a2: AnsiString;
begin
  a1 := s1;
  a2 := s2;
  Result := CompareStringA(LOCALE_USER_DEFAULT, CmpFlags, PChar(a1), Length(a1),
    PChar(a2), Length(a2)) - 2;
end;
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: "Natürliche" Sortierungen von Strings

  Alt 4. Apr 2006, 15:54
Folgende Ergänzung stammt von KingIR.


Im Wesentlichen wurde ein Object File aus der originalen C-Datei erstellt. Der selbe Code wird u.a. auch in den PHP-Funktionen strnatcmp() und natsort() verwendet. Das Object File kann jetzt mit folgendem Code ins eigene Projekt gelinkt werden:

Delphi-Quellcode:
{$INCLUDE 'CHelpers.pas'}

{$LINK 'strnatcmp.obj'}

function _strnatcmp(const a, b: PChar): Integer; cdecl; external;
function _strnatcasecmp(const a, b: PChar): Integer; cdecl; external;


function NatCompareText(const S1, S2: String): Integer;
begin
  Result := _strnatcasecmp(PChar(S1), PChar(S2));
end;


function NatCompareStr(const S1, S2: String): Integer;
begin
  Result := _strnatcmp(PChar(S1), PChar(S2));
end;
Die Datei CHelpers.pas ist in der angehängten ZIP-Datei enthalten. Um nun eine TStringList "natürlich" zu sortieren, geht man z.B. folgendermaßen vor:

Delphi-Quellcode:
uses strnatcmp;
 
 // ...
 
 function Compare_NaturalSort(List: TStringList; Index1, Index2: Integer): Integer;
 begin
   Result := NatCompareText(List[Index1], List[Index2]);
 end;
 
 // ...
 
 var
   FileNames: TStringList;
 
 // ...
 
 FileNames.CustomSort(Compare_NaturalSort); // apply natural sorting
 
 // ...
Angehängte Dateien
Dateityp: zip strnatcmp4delphi_448.zip (4,9 KB, 92x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: "Natürliche" Sortierungen von Strings

  Alt 27. Jun 2006, 13:50
H4ndy hat die strnatcmp.c komplett nach Delphi übersetzt.

Im Anhang befindet sich sein übersetzter Quellcode.


Edit: Aktuelle Version hochgeladen
Angehängte Dateien
Dateityp: pas strnatcomp_136.pas (7,9 KB, 302x aufgerufen)
  Mit Zitat antworten Zitat
Antwort Antwort

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 05:56 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