begin process at 2008 05 16 08:53:40
1 173 235 membres
76 nouveaux aujourd'hui
13 970 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

COMPARAISON ENTRE 2 CHAINES, RETOURNE UN POURCENTAGE DE RESSEMBLANCE (DUPONT = 66,67% DE DURAND)


Information sur la source

Catégorie :Texte Niveau : Initié Date de création : 12/04/2005 Vu / téléchargé: 7 344 / 419

Note :
9,33 / 10 - par 3 personnes
9,33 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (10)
Ajouter un commentaire et/ou une note


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

  • '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
'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
Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

  • signaler à un administrateur
    Commentaire de celiphane le 12/04/2005 00:25:13

    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

  • signaler à un administrateur
    Commentaire de FoxTrot le 12/04/2005 12:06:17

    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

  • signaler à un administrateur
    Commentaire de celiphane le 12/04/2005 15:10:42

    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

  • signaler à un administrateur
    Commentaire de FoxTrot le 12/04/2005 17:44:05

    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

  • signaler à un administrateur
    Commentaire de Neo.balastik le 12/04/2005 21:13:42

    Un genre de source que je n'avais encore jamais rencontré.  Cela pourrait être intéressant pour des requêtes sur un DB.
    Bravo.

  • signaler à un administrateur
    Commentaire de asem67 le 13/04/2005 22:34:23

    Slt.
    j'ai essayer de comparer des images, et non ça ne fonctionne pas .

    qq serait comment faire ???

    Merci pour la source c nickel !!

  • signaler à un administrateur
    Commentaire de celiphane le 13/04/2005 23:30:05

    mon dieu mon dieu...
    nan c'est pas fait pour les images.   <-(

    Encore que, avec un tout petit peu d'effort, en transformant les images en 256 couleurs, en mettant chaque octets de l'une dans le tableau b1 et pareil pour l'autre dans b2,

    on puisse peut-être obtenir un pourcentage de ressemblance entre les 2 images... à essayer... personnellement je le ferais facilement mais j'en ai pas le temps... ni l'envie, ni le besoin d'ailleurs (ce qui concorde peut-être avec le fait que j'ai pas le temps ?)

    @+
    Celiphane

  • signaler à un administrateur
    Commentaire de asem67 le 14/04/2005 00:05:57

    j'ai trouver

    apres qq modif ça me convient tres bien

    ce que g trouver:
    http://www.vbfrance.com/code.aspx?ID=5917

  • signaler à un administrateur
    Commentaire de celiphane le 14/04/2005 00:18:57

    C'est clair que de toute facon ça n'a rien à voir... je vois pas pourquoi d'ailleurs tu est venu sur cette source (la mienne)

    ;-)

    Ici, c'est pour comparer le pourcentage de similitude entre 2 chaines de caractères lol

    Enfin, je suis content pour toi que tu ais trouvé ton bonheur...
    @+
    Celiphane

  • signaler à un administrateur
    Commentaire de Zickos le 19/04/2005 08:22:12

    Salut,

    j'aimerais bien implémenter cette fonction en C++ car c'est exactement ce que j'ai besoin.  Si tu sais où je pourrais trouver le code déja fait ce serait cool, sinon j'aimerais bien avoir le pseudo code de ta fonction car le VB c'est pas ma branche.  Connais-tu la méthode Oliver93, celle utilisée pour la fonction similar_text() de php et qui permet de trouver un pourcentage de similitude entre 2 chaînes de caractères?

    Merci
    @+

Ajouter un commentaire

Appels d'offres

Pub



CalendriCode

Mai 2008
LMMJVSD
   1234
567891011
12131415161718
19202122232425
262728293031 

VS Express FR Gratuit !

VS Express en français et 100% gratuit !

Boutique

Boutique de goodies CodeS-SourceS