Grâce à smirkingman pour le bon code postal. Ici est une version optimisée.
1) l'Utilisation de l'Asc(Mid$(s1, i, 1) à la place. Numérique comparaison est généralement plus rapide que le texte.
2) Utilisez la Mi$ istead de Milieu des depuis le, plus tard, est la variante du ver. et en ajoutant $ est la chaîne de ver.
3) l'Utilisation de fonction d'application pour min. (préférence personnelle uniquement)
4) l'Utilisation d'Entiers puisque c'est ce qu'excel utilise en mode natif.
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
Mise à JOUR:
Pour ceux qui le veulent: je pense qu'il est sûr de dire que la plupart des gens utilisent Levenshtein pour calculer correspondance floue pourcentages. Voici une façon de le faire, et j'ai ajouté une optimisation que vous pouvez spécifier le min. match % de retour (la valeur par défaut est de 70%+. Vous entrez percentags comme "50" ou "80", ou "0" pour exécuter la formule, peu importe).
Le boost de vitesse vient du fait que la fonction va vérifier si il est même possible que c'est le pourcentage de la donner par la vérification de la longueur des 2 chaînes. A noter qu'il existe certains domaines où cette fonction peut être optimisé, mais j'ai gardé ce par souci de lisibilité. J'ai concaténé la distance dans le résultat pour la preuve de la fonctionnalité, mais vous pouvez jouer avec elle :)
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