Strings vergleichen

  • Hallo,

    wie kann ich dieses Problem lösen?

    [autoit]

    $Str1 = '"Sweet About Me":Gabriella Cilmi'
    $Str2 = 'Gabriella Cilmi: "Sweet About Me"'

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    MsgBox(0, "", _CompareString($Str1, $Str2))

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func _CompareString($Value1, $Value2)

    [/autoit][autoit][/autoit][autoit]

    EndFunc ;==>_CompareString

    [/autoit]

    Ich hab das schon die ganze Zeit versucht es mit Stringsplit usw. zu vergleichen, ob diese Strings gleich sind doch es klappt einfach nicht. Wie ürdet ihr das machen? :huh:

  • Ich glaub über so ne Funktion hab ich hier letztens noch n Thema gesehen, da ging es auch um Musik-Titel... Find das Thema grad nit mehr, aber ich mein das Ergebnis war: Es gibt so ne Funktion, aber die ist seeeehhhr langsam. Wenn ich das Thema doch noch finde editier ichs hier rein. :)

    EDIT: Oh, genau das Thema meinte ich :D entweder hatte ich die C-DLL dazu vergessen oda da stand das noch nit in dem Thema.

  • Hi,
    es gibt einen Levenshtein-Algorithmusfür den Vergleich zweier Zeichenketten.
    Aber bei dir sieht es eher nach der Häufigkeit der vorkommenden einzelnen Wörter aus.
    Irgendwo hatte ich mal etwas ähnliches...
    *alteDiskettendurchstöbernd*
    Andy

  • Hi,
    je kleiner der "Abstand" der Levenshtein-Distanz ist (schaut mal bei dem Wikipedia-Link um was es überhaupt geht!), desto ähnlicher sind die Strings. Bei völliger Gleichheit gibt es keinen Abstand, daher ist der Abstand Null!
    Also, "je näher Null, desto besser"^^
    ciao
    Andy
    *edit* habe gerade mal Bernds DLL getestet, da bekommt man als Ergebnis für die vollständige Übereinstimmung 1 und bei völliger Ungleichheit die 0 ;(

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (22. September 2009 um 16:07)

  • Stimmt. Scheint in der .dll genau anders rum umgesetzt zu sein?

    [autoit][/autoit][autoit][/autoit][autoit]

    $Str1 = '"Sweet About Me":Gabriella Cilmi'
    $Str2 = '"Sweet About Me":Gabriella Cilmi'
    $str3 = 'X'

    [/autoit][autoit][/autoit][autoit]

    $hDLL = DllOpen("LevenshteinDistance.dll")
    ConsoleWrite(CompTstr($str1, $str2) & @CRLF)
    ConsoleWrite(CompTstr($str1, $str3) & @CRLF)
    DllClose($hDLL)

    [/autoit][autoit][/autoit][autoit]

    func CompTstr($s, $t)
    local $n, $m
    $n = StringLen($s)
    $m = StringLen($t)
    if $n < $m then $n = $m
    $arDLL = DllCall($hDLL, "int", "LevenshteinDistance", "str", $s, "str", $t)
    If IsArray($arDLL) Then Return ($n - $arDLL[0]) / $n
    endfunc

    [/autoit]

    Edit \ Also die .dll arbeitet schon richtig, nur ist der Rückgabewert überraschend.
    Bei: $Str1 = '0123456789' & $Str2 = '012345678X' sind es 0,9, also 10% :whistling:

  • ...wenn man nicht richtig guckt...^^
    Bernds DLL rechnet völlig richtig, das Ergebnis ist korrekt, wird allerdings in der Funktion durch das

    [autoit]

    ($n - $arDLL[0]) / $n

    [/autoit]

    nochmal "umgedreht". Der Grund erschliesst sich mir nicht....

  • Zitat

    nur ist der Rückgabewert überraschend.
    Bei: $Str1 = '0123456789' & $Str2 = '012345678X' sind es 0,9, also 10%

    Nein, genau so muss es sein, ich war auch erst auf dem falschen Dampfer...
    Wenn 10% des Strings ausgetauscht werden, dann ist der String gleich, so in etwa....

    Für das Beispiel

    [autoit]

    $Str1 = '"Sweet About Me":Gabriella Cilmi'
    $Str2 = 'Gabriella Cilmi: "Sweet About Me"'

    [/autoit]

    ist dieser Vergleich denkbar ungeeignet, da bei Levenshtein ja die einzelnen Buchstaben der Strings miteinander verglichen werden.

    Man müsste also die einzelnen Wörter extrahieren und miteinander vergleichen...

  • Spoiler anzeigen
    [autoit]

    Func _StringSameLetters($String1, $String2)
    Local $count1 = 0
    Local $count2 = 0
    Local $diff = 0
    Local $StrInStr = 0

    [/autoit] [autoit][/autoit] [autoit]

    $Len1 = StringLen($String1)
    $Len2 = StringLen($String2)

    [/autoit] [autoit][/autoit] [autoit]

    ;length is not equal
    If $Len1 <> $Len2 Then Return -1

    [/autoit] [autoit][/autoit] [autoit]

    $Split1 = StringSplit($String1, "")
    $Split2 = StringSplit($String2, "")

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $Len1
    $Letter = $Split1[$i]
    For $a = 1 To $Split1[0]
    If $Split1[$a] = $Letter Then
    $count1 += 1
    EndIf
    Next
    For $b = 1 To $Split2[0]
    If $Split2[$b] = $Letter Then
    $count2 += 1
    EndIf
    Next
    $diff = Abs(($count1-$count2))
    $count1 = 0
    $count2 = 0
    Next
    Return $diff
    EndFunc ;==>_StringSameLetters

    [/autoit]

    Einmal als au3..
    Und als Bernd die DLL gemacht hat habe ich ja das selbe gemacht nur war er früher fertig. Wenn ihr also das Ergebnis abändern wollt wäre hier ein gültiger Source.

    Spoiler anzeigen
  • teste das mal.....

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    $hDLL = DllOpen("LevenshteinDistance.dll")

    [/autoit] [autoit][/autoit] [autoit]

    $Str1 = '"Sweet About Me":Gabriella Cilmi'
    $Str2 = 'Gabriella Cilmi: "Sweet About Me"'

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $arr1=stringsplit($str1,""" :",0)
    _arraysort($arr1,1)
    _arraydisplay($arr1)
    $str1=_arraytostring($arr1,"")
    $arr2=stringsplit($str2,""" :",0)
    _arraysort($arr2,1)
    _arraydisplay($arr2)
    $str2=_arraytostring($arr2,"")

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $dist=CompTstr($str1, $str2)
    msgbox(0,0,$dist)
    DllClose($hDLL)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    func CompTstr($s, $t)
    local $n, $m
    $n = StringLen($s)
    $m = StringLen($t)
    if $n < $m then $n = $m
    $arDLL = DllCall($hDLL, "int", "LevenshteinDistance", "str", $s, "str", $t)
    _arraydisplay($ardll)
    If IsArray($arDLL) Then Return ($n - $arDLL[0]) / $n
    endfunc

    [/autoit]
  • Danke schonmal für die hilfreichen Antworten. Soweit bin ich jetzt gekommen, aber wie mache ich es, das die Traytips nur bei neuen Songs erscheint?

    Spoiler anzeigen
    [autoit]

    #include <Includes\Plug-In.au3>
    #include <Inet.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $Url = "http://www.einslive.de/radiotext/RADIOTXT.TXT"
    Global $Old, $New

    [/autoit] [autoit][/autoit] [autoit]

    AdlibEnable("_GetCurrentSong", 5000)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Sleep(20)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetCurrentSong()
    $Source = _INetGetSource($Url)
    $New = _ConvertSongname($Source)
    If $New <> $Old Then
    TrayTip("", $Source, 5, 1)
    $Old = $New
    EndIf
    EndFunc ;==>_GetCurrentSong

    [/autoit] [autoit][/autoit] [autoit]

    Func _ConvertSongname($String)
    Local $Str = StringReplace($String, " ", "")
    $Str = StringReplace($Str, '"', "")
    Return StringReplace($Str, ':', "")
    EndFunc ;==>_ConvertSongname

    [/autoit] [autoit][/autoit] [autoit]

    Func _StringSameLetters($String1, $String2)
    Local $count1 = 0
    Local $count2 = 0
    Local $diff = 0
    Local $StrInStr = 0

    [/autoit] [autoit][/autoit] [autoit]

    $Len1 = StringLen($String1)
    $Len2 = StringLen($String2)

    [/autoit] [autoit][/autoit] [autoit]

    If $Len1 <> $Len2 Then Return -1

    [/autoit] [autoit][/autoit] [autoit]

    Local $Split1 = StringSplit($String1, "")
    Local $Split2 = StringSplit($String2, "")

    [/autoit] [autoit][/autoit] [autoit]

    For $i = 1 To $Len1
    $Letter = $Split1[$i]
    For $a = 1 To $Split1[0]
    If $Split1[$a] = $Letter Then
    $count1 += 1
    EndIf
    Next
    For $b = 1 To $Split2[0]
    If $Split2[$b] = $Letter Then
    $count2 += 1
    EndIf
    Next
    $diff = Abs(($count1 - $count2))
    $count1 = 0
    $count2 = 0
    Next
    Return $diff
    EndFunc ;==>_StringSameLetters

    [/autoit]
  • ich hab mich mal aus Langeweile an die Vergleichsfunktion gemacht ...

    In der Funktion wird nur mit Buchstaben verglichen.
    Sonderzeichen und Zahlen und der gleichen werden nicht berücksichtigt.

    Vielleicht ist das ja hilfreich :)

    Spoiler anzeigen
    [autoit]

    #include <Array.au3>
    ; benötigt die LevenshteinDistance.dll von Bernd670

    [/autoit] [autoit][/autoit] [autoit]

    $Str1 = '"Sweet(&%$§"!$ 123_About Me":Gabriella Cilmi'
    $Str2 = 'Gabriella Cilmi: "Sweet About Me"'

    [/autoit] [autoit][/autoit] [autoit]

    MsgBox(0,'', CompTwoStr($Str1, $Str2))

    [/autoit] [autoit][/autoit] [autoit]

    Func CompTwoStr($s, $t)
    Local $a_str1, $a_str2, $a_str1_result, $a_str2_result
    Local $hDLL = DllOpen("LevenshteinDistance.dll")
    Local $n = StringLen($s)
    Local $m = StringLen($t)
    If $n < $m Then $n = $m
    $a_str1=StringSplit(StringRegExpReplace($s, '\W|_|[0-9]', " ")," ",2)
    _arraysort($a_str1)
    $a_str1_result = _ArrayFindAll($a_str1, "")
    For $i = 1 To UBound($a_str1_result)
    _ArrayDelete($a_str1,$a_str1_result[0])
    Next
    $s = _ArrayToString($a_str1,"")
    $a_str2=StringSplit(StringRegExpReplace($t, '\W|_|[0-9]', " ")," ",2)
    _arraysort($a_str2)
    $a_str2_result = _ArrayFindAll($a_str2, "")
    For $i = 1 To UBound($a_str2_result)
    _ArrayDelete($a_str2,$a_str2_result[0])
    Next
    $t = _ArrayToString($a_str2,"")
    $arDLL = DllCall($hDLL, "int", "LevenshteinDistance", "str", $s, "str", $t)
    DllClose($hDLL)
    If IsArray($arDLL) Then Return ($n - $arDLL[0]) / $n
    EndFunc

    [/autoit]

    Edit: hatte ganz übersehen, dass dabei noch nicht Zahlen und der Unterstrich mit gefiltert werden.
    Jetzt sollte es aber passen ;)

    MfG Schnuffel

    "Sarkasmus ist die niedrigste Form des Witzes, aber die höchste Form der Intelligenz."
    Val McDermid

    ein paar Infos ...

    Wer mehr als "nur" Hilfe benötigt, kann sich gern im Forum "Programmieranfragen" an uns wenden. Wir helfen in allen Fällen, die die Forenregeln zulassen.

    Für schnelle Hilfe benötigen wir ein ! lauffähiges ! Script, dass wir als Demonstration des Problems testen können. Wer von uns erwartet ein Teilscript erstmal lauffähig zu bekommen, der hat
    1. keine wirkliche Not
    2. keinen Respekt vor Menschen die ihm in ihrer Freizeit Ihre Hilfe anbieten
    3. oder ist einfach nur faul und meint wir coden das für ihn

    In solchen Fällen erlaube ich mir, die Anfrage einfach zu ignorieren. ;)

    2 Mal editiert, zuletzt von Schnuffel (23. September 2009 um 16:16)