Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Ähnlichkeitssuche: Fuzzy-Search-Unit??? (https://www.delphipraxis.net/44298-aehnlichkeitssuche-fuzzy-search-unit.html)

glkgereon 18. Apr 2005 10:52

Re: Ähnlichkeitssuche: Fuzzy-Search-Unit???
 
ach sch****

es soll zurückgeben, ob es gematched hat, also ob der string drin war.
der typ is natürlich boolean.
das is einer meiner häufigsten fehler :wall:


Zitat:

Außerdem, wenn ich es richtig verstehe, sind die geposteten Lösungen immer noch eine Konsole-Anwendung oder ein Teil davon.
ich bitte dich, alles is in functions, du muss sie einfach nur kopieren.

und die 2 zeilen wo geprüft wird ob der aufruf gültig ist solltest du noch mitnehmen...

romber 18. Apr 2005 11:00

Re: Ähnlichkeitssuche: Fuzzy-Search-Unit???
 
Das hier war auch mein Problem:

Delphi-Quellcode:
...
TextLen:=PrepareTheString(AllStr, TextPara) + 1;
...
[Error] Project1.dpr(105): Incompatible types: 'String' and 'Text'

leddl 18. Apr 2005 11:06

Re: Ähnlichkeitssuche: Fuzzy-Search-Unit???
 
Also das Einsetzen in dein Programm sollte doch kein Problem sein... So wie ich das verstanden habe, hast du es doch auch schon gemacht, aber die For-Schleife machte Probleme, oder? :wiejetzt:

Was genau funktioniert denn jetzt zB an dem von mir gepostetem Code-Teil nicht?

//Edit:
Ich hab jetzt aus reiner Neugier doch mal mein Delphi angeschmissen. Die 2005 Personal compiliert mir die Konsolenanwendung in der Ursprungsfassung nicht - ebenfalls mit Verweis auf die Erhöhung der Schleifenvariablen. So und nicht anders hatte ich es erwartet.
Setze ich meine Funktion (mit einer kleinen Änderung allerdings - der Code war furchtbar formatiert und ich hab doch glatt das inc(i) an die falsche Stelle gesetzt! :wall: Einfach eine Zeile nach oben verschieben, dann stimmts) ein, dann compiliert es.

//Edit2:
Wo genau tritt der Fehler denn jetzt auf? In der Konsolenanwendung oder wenn du versuchst, das umzubauen? Mit solchen Codeschnipseln kann man nichts anfangen. Poste doch einfach mal, was du hast, dann sieht man mehr.

romber 18. Apr 2005 11:32

Re: Ähnlichkeitssuche: Fuzzy-Search-Unit???
 
Die Schleife war leider nicht da einzige Problem. Das Programm ist nach wie vor für eine gleadene Textdatei otimiert, und meine Versuche, einen String statt Textdatei zu übergeben scheiterten mit der oben geposteten Kompeiler-Fehlermeldung. Mann kann eigentlich hier sehr lange diskutieren. Kann jemand von Speziealisten hier vielleicht so nett sein und diesen kleinen Unit komplett fur Form-Anwendung umzuschreiben? Ich lese hier, dass es eigentlich ganz eifach ist. Einmal den kompletten fertigen Unit hier posten und alle sind zufrieden. Dann könnte man das auch der Code-Library hinzufügen, weil diese Fuzzy-Search an sich eine sehr hilfreiche Sache ist.

Function FuzzyMatching (Suchbegriff: string; Uebereinstimmung: integer; Quelle: string): Boolean;

und das war's.

romber 18. Apr 2005 11:45

Re: Ähnlichkeitssuche: Fuzzy-Search-Unit???
 
Zitat:

Zitat von leddl
Wo genau tritt der Fehler denn jetzt auf? In der Konsolenanwendung oder wenn du versuchst, das umzubauen? Mit solchen Codeschnipseln kann man nichts anfangen. Poste doch einfach mal, was du hast, dann sieht man mehr.

Genau! Ich brauche keine Konsolen-Anwendung! Ich lade dynamisch die Quellcode eine Web-Seite und möchte wissen, ob ein bestimmtes Wort oden eine änliche da in dem Quellcode vorhnden ist (Boolean) . Mehr nicht!

Diverse Fehler erscheinen, wenn ich versuche den Unit umzubauen. Mit diesen ganzen TextBuffer, InFile vom Typ Text, ReadLn, WriteLn etc... Meine Kenntnisse sind leider nicht ausreichend, um das Problem selbst zu lösen. Deswegen bin ich auch hier.

leddl 18. Apr 2005 12:12

Re: Ähnlichkeitssuche: Fuzzy-Search-Unit???
 
Sorry, dafür hab ich im Moment gerade keine Zeit. Aber so schwer is das nun wirklich auch nicht. Du mußt einfach nur die Datei InFile durch deinen String ersetzen - dann natürlich auch die Aufrufe dementsprechend ändern - und die Ausgaben an die Konsole sinnvoll in Rückgabewerte umwandeln.

Vielleicht schaff ichs heut nacht mal, mich da dran zu setzen.

atreju2oo0 18. Apr 2005 12:26

Re: Ähnlichkeitssuche: Fuzzy-Search-Unit???
 
Diese Funktionen benutze ich dafür...
Läuft im Endeffekt aufs selbe hinaus!
Wo ich die herhabe weiß ich leider nciht mehr genau, aber hier im DP-Forum wurde mir nen Link gegeben...


Delphi-Quellcode:
var
  FiR0 : integer;
  FiP0 : integer;
  FiQ0 : integer;


procedure LevenshteinPQR(p,q,r:integer);
begin
  FiP0 := p;
  FiQ0 := q;
  FiR0 := r;
end;

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;

Aufrufen muss man erst die "Init"
mit LevenshteinPQR(1, 1, 1);

und dann kannste mit
LevenshteinDistance(String1,string2)<=fuzzyEntfern ung
die Entfernung der Stirngs herausbekommen

glkgereon 18. Apr 2005 12:54

Re: Ähnlichkeitssuche: Fuzzy-Search-Unit???
 
So, mir platzt gleich der kragen!!!


WO IST MEINE VERSION AUF EINE TEXTDATEI OPTIMIERT????? :evil:

nimm sie und sag was net funzt!
aber meine version die ich gepostet hab hat sowohl die while-schleife drin als auf die änderung auf string.

WAS BITTE WILLST DU MEHR VON UNS???? :evil:

leddl 18. Apr 2005 13:03

Re: Ähnlichkeitssuche: Fuzzy-Search-Unit???
 
:gruebel: War ich das? :gruebel: :mrgreen: 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. :oops: Aber Respekt, du warst uns allen voraus. :thumb:

schöni 18. Apr 2005 15:13

Re: Ähnlichkeitssuche: Fuzzy-Search-Unit???
 
Hallo leddl!

Habe Deinen Code getestet. Aber das Ergebnis von Similarest ist bei mir immer gleich 1.

Wie krige ich die Asgabe der gefundenen Textstellen hin. Diese können ja dann auch in eine Stringliste zeilenweise übernommen werden.

schöni


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:41 Uhr.
Seite 2 von 3     12 3      

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