Danke für den schönen Code Beitrag smirkingman. Hier ist eine optimierte Version.
1) Verwenden Sie Asc (Mid $ (s1, i, 1) statt. Numerical Vergleich ist in der Regel schneller als Text.
2) Verwenden Sie Mid $ istead von Mid seit der später ist die Variante ver. und das Hinzufügen von $ ist String ver.
3) Anwendungsfunktion für min. (nur persönliche Vorlieben)
4) Verwenden Sie Long statt Integer, da es genau das ist, was Excel verwendet.
Function Levenshtein(ByVal string1 As String, ByVal string2 As String) As Long
Dim i As Long, j As Long
Dim string1_length As Long
Dim string2_length As Long
Dim distance() As Long
string1_length = Len(string1)
string2_length = Len(string2)
ReDim distance(string1_length, string2_length)
For i = 0 To string1_length
distance(i, 0) = i
Next
For j = 0 To string2_length
distance(0, j) = j
Next
For i = 1 To string1_length
For j = 1 To string2_length
If Asc(Mid$(string1, i, 1)) = Asc(Mid$(string2, j, 1)) Then
distance(i, j) = distance(i - 1, j - 1)
Else
distance(i, j) = Application.WorksheetFunction.Min _
(distance(i - 1, j) + 1, _
distance(i, j - 1) + 1, _
distance(i - 1, j - 1) + 1)
End If
Next
Next
Levenshtein = distance(string1_length, string2_length)
End Function
UPDATE:
Für diejenigen, die es wollen: Ich denke, es ist sicher zu sagen, dass die meisten Menschen Levenshtein Abstand verwenden Fuzzy-Match Prozentsätze zu berechnen. Hier ist eine Möglichkeit, dies zu tun, und ich habe eine Optimierung hinzugefügt, die Sie die min angeben können. passe% an, um zurückzukehren (Standard ist 70% +. Du gibst Prozentzahlen wie "50" oder "80" oder "0" ein, um die Formel unabhängig auszuführen).
Die Geschwindigkeitssteigerung kommt von der Tatsache, dass die Funktion prüft, ob es sogar möglich ist, dass es innerhalb des Prozentsatzes ist, den Sie geben, indem Sie die Länge der 2 Zeichenfolgen überprüfen. Bitte beachten Sie, dass es einige Bereiche gibt, in denen diese Funktion optimiert werden kann, aber ich habe sie aus Gründen der besseren Lesbarkeit beibehalten. Ich verkettet, um die Strecke in Folge für den Nachweis der Funktionalität, aber man kann mit ihm Geige :)
Function FuzzyMatch(ByVal string1 As String, _
ByVal string2 As String, _
Optional min_percentage As Long = 70) As String
Dim i As Long, j As Long
Dim string1_length As Long
Dim string2_length As Long
Dim distance() As Long, result As Long
string1_length = Len(string1)
string2_length = Len(string2)
' Check if not too long
If string1_length >= string2_length * (min_percentage/100) Then
' Check if not too short
If string1_length <= string2_length * ((200 - min_percentage)/100) Then
ReDim distance(string1_length, string2_length)
For i = 0 To string1_length: distance(i, 0) = i: Next
For j = 0 To string2_length: distance(0, j) = j: Next
For i = 1 To string1_length
For j = 1 To string2_length
If Asc(Mid$(string1, i, 1)) = Asc(Mid$(string2, j, 1)) Then
distance(i, j) = distance(i - 1, j - 1)
Else
distance(i, j) = Application.WorksheetFunction.Min _
(distance(i - 1, j) + 1, _
distance(i, j - 1) + 1, _
distance(i - 1, j - 1) + 1)
End If
Next
Next
result = distance(string1_length, string2_length) 'The distance
End If
End If
If result <> 0 Then
FuzzyMatch = (CLng((100 - ((result/string1_length) * 100)))) & _
"% (" & result & ")" 'Convert to percentage
Else
FuzzyMatch = "Not a match"
End If
End Function
Dieser Code funktioniert Drag & Drop für Access VBA zu verbessern. :) – HelloW
Schnelle Notiz für zukünftige Benutzer, VBA 'Integer' deklariert * sollte * weniger Speicher verwenden und schneller sein, aber sie werden jetzt automatisch in den' Long' Typ hinter den Kulissen konvertiert (Quelle: [MSDN] (https: // msdn .microsoft.com/de-us/library/office/aa164506 (v = Büro.10) .aspx), siehe auch [http://stackoverflow.com/a/26409520/6609896]. Für eine marginale Leistungssteigerung bedeutet das Erklären von allen als "Lang" die interne Umwandlungszeit (einige andere Antworten, die ich gesehen habe, haben dies ausgenutzt). ODER, wenn Ihre Strings weniger als 255 Zeichen lang sind, deklarieren Sie als 'Bytes', da dies noch weniger Speicher als 'Integer' erfordert. – Greedo