Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Vergleichen von 2 Strings (prozentual) (https://www.delphipraxis.net/154811-vergleichen-von-2-strings-prozentual.html)

Chillkröte 26. Sep 2010 14:15

Vergleichen von 2 Strings (prozentual)
 
Hallo
ich sitze jetzt von seit einiger zeit vor dem Problem, 2 Strings prozentual zu vergleichen.
Diese Funktion bietet das zwar schon an, jedoch ist das Ergebnis nicht befriedigend.
Es geht um folgende strings (aus der luft gegriffen)
Code:
"sdfsd-fgdfdf Hier.Der.Beispiel.Text-sdf-dff-ddd"

"Hier der Beispiel Text"
bei der oben verlinkten Funktion wird nur bis zum Ende des kürzeren Strings verglichen und demzufolge kommt kein vernünftiges Ergebnis bei raus.

Hat jemand Lösungsvorschläge?

mkinzler 26. Sep 2010 14:17

AW: Vergleichen von 2 Strings (prozentual)
 
Was verstehst du unter "prozentual Vergleicehn"?

daywalker9 26. Sep 2010 14:23

AW: Vergleichen von 2 Strings (prozentual)
 
Ich würde dem Link zu folge tippen, zu wieviel Prozent die Strings identisch sind..

Chillkröte 26. Sep 2010 14:26

AW: Vergleichen von 2 Strings (prozentual)
 
@daywalker9
genau

Delphi-Quellcode:
function DoStringMatch(s1, s2: string): Double;
var
  i, iMin, iMax, iSameCount: Integer;
begin
  iMax := Max(Length(s1), Length(s2));
  iMin := Min(Length(s1), Length(s2));
  iSameCount := -1;
  for i := 0 to iMax do
  begin
//    if i > iMin then
//      break;
    if s1[i] = s2[i] then
      Inc(iSameCount)
//    else
//      break;
  end;
  if iSameCount > 0 then
    Result := (iSameCount / iMax) * 100
  else
    Result := 0.00;
end;
so müsste das eig gehen
(gleichheit bei 12%)
irgendwie steh ich momentan echt aufn schlauch...

Chillkröte 26. Sep 2010 14:34

AW: Vergleichen von 2 Strings (prozentual)
 
das problem ist aber noch bei solchen strings

Delphi-Quellcode:
doStringMatch('exp_onkelcharliexvid_s06e24','Onkel Charlie S06 E24');

gleichheit = 0, was ja auch logisch ist, da die zeichen nicht übereinstimmen

stahli 26. Sep 2010 14:38

AW: Vergleichen von 2 Strings (prozentual)
 
Schau mal hier, ob´s Dir was hilft.
Mit einer kleinen Anpassung könnten auch Teiltexte akzeptiert werden.

hans ditter 26. Sep 2010 14:44

AW: Vergleichen von 2 Strings (prozentual)
 
Ich würde erstmal die beiden Längen der Strings ermitteln, dann eine Schleife für die Länge des längeren Strings einsetzten.
In der Schleife dann überprüfen, ob die überprüften Buchstaben an der Stelle gleich sind, wenn ja, dann in die eine Variable (z.B. BuchsGleich) speichern, wenn nicht, in eine andere.
Am Ende dann die Länge des längeren Strings durch 100 und mal die gleichen (bzw. ungleichen, wenn man auf prozentuale Ungleichheit prüfen möchte) Buchstaben nehmen.

Ungetesteter Code!!
Delphi-Quellcode:
var BuchsGleich, BuchsUngleich, Länge: Integer;//Länge = Länge der Schleife
    string1, string2: String;//deine beiden Strings
    lString1, lString2: integer;//Länge deiner beiden Strings
    helpStr1, helpStr2: string;//braucht man zum Vergleichen
    CopyStart: integer;//Startposition des Kopiervorgangs
begin
  lString1:=length(string1);   lString2:=length(string2);
  if lString1 > lString2 then Länge:=lString1
  else Länge:=lString2;
  CopyStart:=0;
  for i:=1 to Länge do//hier beginnt deine Prüfschleife
  begin
    helpStr1:=LowerCase(Copy(string1,CopyStart,1));  helpStr2:=LowerCase(Copy(string2,CopyStart,1));
    {die beiden Zeichen herauslösen, LowerCase notwendig, da man dann auch solche Strings vergleichen kann: 'BAUM' und 'baum'}
    if helpStr1 = helpStr2 then BuchsGleich:= BuchsGleich + 1
    else BuchsUngleich:= BuchsUngleich + 1;
    CopyStart:=CopyStart + 1;
  end
end

Sir Rufo 26. Sep 2010 14:48

AW: Vergleichen von 2 Strings (prozentual)
 
Ich habe hier den Quelltext zu einer Fuzzy-Suche, die ergibt bei deinem Beispiel eine Übereinstimmung von 55.21%
Delphi-Quellcode:
unit insFuzzy;

interface

function FuzzyMatching( const SearchIn, SearchStr : string ) : extended;

implementation

const
  MaxParLen = 255;

  (***************************************************************************)

function PrepareTheString( const OriginStr : string; var ConvStr : string )
  : Integer;
  var
    i : Integer;
  begin
    ConvStr := OriginStr;

    for i := 1 to Length( OriginStr ) do
      begin
        ConvStr[ i ] := UpCase( ConvStr[ i ] );
        if ( ConvStr[ i ] < '0' ) then
          ConvStr[ i ] := ' '
        else
          case ConvStr[ i ] of
            Chr( 196 ) :
              ConvStr[ i ] := Chr( 228 );
            Chr( 214 ) :
              ConvStr[ i ] := Chr( 246 );
            Chr( 220 ) :
              ConvStr[ i ] := Chr( 252 );
            Chr( 142 ) :
              ConvStr[ i ] := Chr( 132 );
            Chr( 153 ) :
              ConvStr[ i ] := Chr( 148 );
            Chr( 154 ) :
              ConvStr[ i ] := Chr( 129 );
            ':' :
              ConvStr[ i ] := ' ';
            ';' :
              ConvStr[ i ] := ' ';
            '<' :
              ConvStr[ i ] := ' ';
            '>' :
              ConvStr[ i ] := ' ';
            '=' :
              ConvStr[ i ] := ' ';
            '?' :
              ConvStr[ i ] := ' ';
            '[' :
              ConvStr[ i ] := ' ';
            ']' :
              ConvStr[ i ] := ' ';
          end;
      end;

    PrepareTheString := i;
  end;

(***************************************************************************)

function NGramMatch( const TextPara, SearchStr : string;
  SearchStrLen, NGramLen : Integer; var MaxMatch : Integer ) : Integer;

  var
    NGram : string[ 8 ];
    NGramCount : Integer;
    i, Count : Integer;

  begin
    NGramCount := SearchStrLen - NGramLen + 1;
    Count := 0;
    MaxMatch := 0;

    i := 1;
    while i <= NGramCount do
      begin
        NGram := Copy( SearchStr, i, NGramLen );
        if ( NGram[ NGramLen - 1 ] = ' ' ) and ( NGram[ 1 ] <> ' ' ) then
          Inc( i, NGramLen - 3 ) (* Wird in der Schleife noch erhoeht! *)
        else
          begin
            Inc( MaxMatch, NGramLen );
            if Pos( NGram, TextPara ) > 0 then
              Inc( Count );
          end;
        Inc( i );
      end;

    NGramMatch := Count * NGramLen;
  end;

(***************************************************************************)

function FuzzyMatching( const SearchIn, SearchStr : string ) : extended;

  var
    SStr : string;
    TextPara : string;
    TextBuffer : string;
    TextLen : Integer;
    SearchStrLen : Integer;
    NGram1Len : Integer;
    NGram2Len : Integer;
    MatchCount1 : Integer;
    MatchCount2 : Integer;
    MaxMatch1 : Integer;
    MaxMatch2 : Integer;
    Similarity : extended;
    BestSim : extended;

  begin

    BestSim := 0.0;

    if ( SearchIn <> '' ) and ( SearchStr <> '' ) then
      begin
        SearchStrLen := PrepareTheString( SearchStr, SStr );
        NGram1Len := 3;
        if SearchStrLen < 7 then
          NGram2Len := 2
        else
          NGram2Len := 5;

        TextBuffer := SearchIn;
        TextLen := PrepareTheString( TextBuffer, TextPara ) + 1;
        TextPara := Concat( ' ', TextPara );

        if TextLen < MaxParLen - 2 then
          begin
            MatchCount1 := NGramMatch( TextPara, SStr, SearchStrLen, NGram1Len,
              MaxMatch1 );
            MatchCount2 := NGramMatch( TextPara, SStr, SearchStrLen, NGram2Len,
              MaxMatch2 );
            Similarity := 100.0 * ( MatchCount1 + MatchCount2 ) /
              ( MaxMatch1 + MaxMatch2 );
            if Similarity > BestSim then
              BestSim := Similarity;
          end;
      end;

    RESULT := BestSim;

  end;

end.

hans ditter 26. Sep 2010 14:55

AW: Vergleichen von 2 Strings (prozentual)
 
@ Sir Rufo
Mein Gott ist die Funktion lang... ist der Aufwand wirklich nötig, um 2 Strings miteinander zu vgl??

stahli 26. Sep 2010 14:57

AW: Vergleichen von 2 Strings (prozentual)
 
Meine liefert bei

"sdfsd-fgdfdf Hier.Der.Beispiel.Text-sdf-dff-ddd" : "Hier der Beispiel Text" = 95%
und
"exp_onkelcharliexvid_s06e24" : "Onkel Charlie S06 E24" = 94%


PS: Wie lang die Funktion ist, ist doch egal ;-)
Und ob eine Ähnlichkeit von 0 logisch ist oder nicht, kommt wohl immer auf die jeweiligen Ansprüche an.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:44 Uhr.
Seite 1 von 3  1 23      

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