Comparaison entre 2 chaines, retourne un pourcentage de ressemblance (dupont = 66,67% de durand)

Soyez le premier à donner votre avis sur cette source.

Vue 17 684 fois - Téléchargée 773 fois

Description

Bonjour,

Je vous met là à disposition un fonction qui vous renvoie un pourcentage de similitude entre 2 chaînes de caractères passées en argument.

Cette fonction est l'implémentation d'un modèle mathématiques (Ratcliff, Obershelp, Levenshtein), et utilise une sous-routine.

Vous savez tout, vous trouverez dans l'archive jointe un projet de démonstration.

Source / Exemple :


'Code à coller dans un module
'La fonction s'utilise en appelant la seule procédure publique disponible, Comparer

'implémentation de la méthode de Ratcliff, Obershelp, Levenshtein

Private Declare Sub RtlMoveMemory Lib "kernel32" (Destination As Any, Source As Any, ByVal Length As Long)
Private b1() As Byte
Private b2() As Byte

Public Function Comparer(ByVal string1 As String, ByVal string2 As String) As Double
  Dim len1 As Long
  Dim len2 As Long
  string1 = UCase$(string1)
  string2 = UCase$(string2)
  If string1 = string2 Then
    Comparer = 1
  Else
    len1 = Len(string1)
    len2 = Len(string2)
    ReDim b1(1 To len1)
    ReDim b2(1 To len2)
    RtlMoveMemory b1(1), ByVal string1, len1
    RtlMoveMemory b2(1), ByVal string2, len2
    Comparer = SubSim(1, len1, 1, len2) / (len1 + len2) * 2
  End If
End Function

Private Function SubSim(st1 As Long, end1 As Long, st2 As Long, end2 As Long) As Long
  If Not (st1 > end1 Or st2 > end2 Or st1 <= 0 Or st2 <= 0) Then
    Dim c1 As Long
    Dim c2 As Long
    Dim ns1 As Long
    Dim ns2 As Long
    Dim i As Long
    Dim max As Long
    For c1 = st1 To end1
      For c2 = st2 To end2
        i = 0
        Do Until b1(c1 + i) <> b2(c2 + i)
          i = i + 1
          If i > max Then
            ns1 = c1
            ns2 = c2
            max = i
          End If
          If c1 + i > end1 Or c2 + i > end2 Then Exit Do
        Loop
      Next c2
    Next c1
    SubSim = max + SubSim(ns1 + max, end1, ns2 + max, end2) + SubSim(st1, ns1 - 1, st2, ns2 - 1)
  End If
End Function

Conclusion :


Merci de laisser vos commentaires, optimisations s'il y a lieu (ça me semble au top du plus du plus du plus rapide... mais bon, il y a toujours mieux... enfin peut-être !).
Si vous connaissez des fonctions du même genre, présentez les moi, je vous en serais gré !

@+
Celiphane

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

celiphane
Messages postés
466
Date d'inscription
samedi 16 février 2002
Statut
Membre
Dernière intervention
20 avril 2007
-
Pour info, la mise en page du site à bouffer la plupart de mes indentations ;-)

Ne me le reprochez pas, c'est pas de ma faute ! Voir l'archive comme preuve !

@+
Celiphane
cs_FoxTrot
Messages postés
6
Date d'inscription
mardi 18 mars 2003
Statut
Membre
Dernière intervention
13 janvier 2006
-
Et bien, ca fonctionne impec. Juste pour info, toi, dans tes applications, à partir de quelle valeur consière tu qu'il y a risque de doublon ? Moi après quelques essais, j'aurai envie de prendre >0,75

Merci encore.


@+ FoxTrot
celiphane
Messages postés
466
Date d'inscription
samedi 16 février 2002
Statut
Membre
Dernière intervention
20 avril 2007
-
salut.

oui, cette valeur (0.75) me semble correcte.
En fait, selon les champs en présence (nom, prénom, adresse, ville) j'applique à chaque champ une valeur différente (j'oscille entre 0.6 pour être souple sur le nom, si toutefois j'ai d'autres champs sur lesquels je pourrais être plus sévêre, allant jusqu'à 0.85 : ainsi, je peux être léger sur le nom et trancher définitivement grâce au prénom, ou à la ville etc).

Parmi les pièges aussi, faut penser au doublon genre :
"Pr Martin" et "Professeur Martin"
"M. Martin" et "Monsieur Martin"
qui sont de vrais doublons, mais pas si facile à reconnaître pour une machine !

C'est vrai que ce n'est pas LA solution clé en main pour dédoublonner, mais tout de même un sacré outil à exploiter dans ce sens... C'est ensuite au développeur de jouer d'astuces (genre sur une comparaison, ne comparer que le début, puis que la fin des chaînes... etc...)

@+
Celiphane
cs_FoxTrot
Messages postés
6
Date d'inscription
mardi 18 mars 2003
Statut
Membre
Dernière intervention
13 janvier 2006
-
Salut

En effet, un bon complément serait les homophonies ("o" et "au") et les abréviations.

Je suis un newbie, mais je vais essayer pour quelques homophonies.

A plus
Neo.balastik
Messages postés
797
Date d'inscription
jeudi 17 mai 2001
Statut
Membre
Dernière intervention
5 mai 2009
4 -
Un genre de source que je n'avais encore jamais rencontré. Cela pourrait être intéressant pour des requêtes sur un DB.
Bravo.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.