War ich das?
Glaub schon, oder? Zumindest benutz ich die auch und hab sie auch mal hier irgendwo gepostet. Von wem
ich die Funktion hab, weiß ich auch nicht mehr, aber sie funktioniert ganz gut.
Wollte das hier aber nicht posten, da er ja eigentlich eben die FuzzySearch benutzen wollte... ne Moment mal, hat er ja so gar nich gesagt... er hat halt nur die gefunden.
Dann kann man den Levenshtein nur empfehlen. Funktioniert wie gesagt wunderbar.
...
So, hab gekramt und mal meine Funktion rausgesucht. Is im Endeffekt das gleiche, nur hab ich das alles innerhalb einer Gesamtfunktion zusammengefasst, so daß nur noch ein Aufruf benötigt wird.
Die folgende Funktion benötigt als Parameter den zu suchenden String und eine TStrings. Der Rückgabewert ist dann der Index des ähnlichsten TStrings-Elements.
Die Funktion läßt sich natürlich nach Belieben anpassen, mir hat sie so aber ganz gute Dienste erwiesen.
Delphi-Quellcode:
{ --- Sucht in einer Liste nach dem ähnlichsten Text ----------------------- }
function Similarest(aText:
string; aList: TStrings): Integer;
var
Dummy:
string;
MinV : Integer;
i : Integer;
FiR0 : Integer;
FiP0 : Integer;
FiQ0 : Integer;
Dist :
array of Integer;
{ --- Similarest: Subprozedure ------------------------------------------- }
procedure LevenshteinPQR(p,q,r:integer);
begin
FiP0 := p;
FiQ0 := q;
FiR0 := r;
end;
{ LevenshteinPQR }
{ --- Similarest: Subfunktion -------------------------------------------- }
function LevenshteinDistance(
const sString,sPattern:
String): Integer;
const
MAX_SIZE = 50;
var
aiDistance:
array [0..MAX_SIZE,0..MAX_SIZE]
of Integer;
i,j,
iP,iQ,iR,iPP,
iStringLength,
iPatternLength,
iMaxI,iMaxJ : Integer;
chChar : Char;
function Min(X,Y,Z: Integer): Integer;
begin
if (X<Y)
then
Result:=X
else
Result:=Y;
if (Result>Z)
then
Result:=Z;
end;
{ Min }
begin
iStringLength:=length(sString);
if (iStringLength>MAX_SIZE)
then
iMaxI:=MAX_SIZE
else
iMaxI:=iStringLength;
iPatternLength:=length(sPattern);
if (iPatternLength>MAX_SIZE)
then
iMaxJ:=MAX_SIZE
else
iMaxJ:=iPatternLength;
aiDistance[0, 0]:=0;
for i:=1
to iMaxI
do
aiDistance[i, 0]:=aiDistance[i-1, 0]+FiR0;
for j:=1
to iMaxJ
do begin
chChar:=sPattern[j];
if ((chChar='
*')
or (chChar='
?'))
then
iP:=0
else
iP:=FiP0;
if (chChar='
*')
then
iQ:=0
else
iQ:=FiQ0;
if (chChar='
*')
then
iR:=0
else
iR:=FiR0;
aiDistance[0, j]:=aiDistance[0, j-1]+iQ;
for i:=1
to iMaxI
do begin
if (sString[i]=sPattern[j])
then
iPP:=0
else
iPP:=
iP;
{*** aiDistance[i,j] := Minimum of 3 values ***}
aiDistance[i,j]:=Min(aiDistance[i-1, j-1]+iPP,
aiDistance[i, j-1] +iQ,
aiDistance[i-1, j] +iR);
end;
end;
Result:=aiDistance[iMaxI, iMaxJ];
end;
{ LevenshteinDistance }
begin
SetLength(Dist, aList.Count);
LevenshteinPQR(1, 1, 1);
for i := 0
to (aList.Count-1)
do
begin
//Dummy := ExtractFileName(aList.Strings[i]);
//Dummy := Copy(Dummy, 1, Pos('.', Dummy)-1);
Dummy := aList.Strings[i];
Dist[i] := LevenshteinDistance(aText, Dummy);
end;
MinV := 0;
for i := 0
to (Length(Dist)-1)
do
if (Dist[MinV] > Dist[i])
then MinV := i;
Result := MinV;
end;
Ich möchte aber auch nochmal darauf hinweisen, daß diese Funktion nicht von mir stammt. Leider hab ich wie gesagt, vergessen, wo ich sie herhabe. Falls das also jemandem bekannt vorkommt, soll er mir bescheid sagen. Dann kann ich auch gerne einen kleinen Vermerk einfügen.
@glkgereon:
Sachte sachte!
Er hat sichs wohl nich richtig angeschaut. Ich übrigens auch nicht.
Aber Respekt, du warst uns allen voraus.