begin process at 2010 02 10 11:12:54
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Chaîne de caractères

 > DISTANCE DE JARO-WINKLER

DISTANCE DE JARO-WINKLER


 Information sur la source

Note :
Aucune note
Catégorie :Chaîne de caractères Classé sous :Jaro, Winkler, Jaro-Winkler, distance, similarité Niveau :Débutant Date de création :07/04/2009 Date de mise à jour :08/04/2009 21:40:40 Vu :1 311

Auteur : PoulpHunter

Ecrire un message privé
Site perso
Commentaire sur cette source (5)
Ajouter un commentaire et/ou une note

 Description

La distance de Jaro-Winkler mesure la similarité entre deux chaînes de caractères.

Cette fonction permet de renvoyer la valeur de la distance de Jaro-Winkler.
Elle est comprise entre 0 et 1 .

voir :
http://fr.wikipedia.org/wiki/Distance_de_Jaro-Wi nkler

Source

  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <string.h>
  • #define true 0
  • #define false 1
  • #define max(x,y) ((x)>(y)?(x):(y))
  • #define min(x,y) ((x)<(y)?(x):(y))
  • char *TrouverMatches(char * txt,int *bl)
  • {
  • int i,j;
  • char *res=malloc(256*sizeof(char));
  • char ctmp='a';
  • for (i=0;i<256;i++)
  • {res[i]=0;}
  • i=0,j=0;
  • while (ctmp!=0)
  • {
  • ctmp=txt[i];
  • if (bl[i]==true)
  • {
  • res[j]=ctmp;
  • j++;
  • }
  • i++;
  • }
  • return res;
  • }
  • double JaroWinkler(char *t1,char *t2)
  • {
  • int ecartMax,l1,l2,compteMatching,compteTransposition,longueurPrefix,i,j;
  • char *t1Matche,*t2Matche;
  • int *b1,*b2;
  • double distanceJaro;
  • if (t1[0]==0 || t2[0]==0)
  • return 0.0;
  • l1=strlen(t1);
  • l2=strlen(t2);
  • ecartMax=(max(l1,l2)/2)-1;
  • compteMatching=0;
  • b1=malloc((l1+2)*sizeof(int));
  • b2=malloc((l2+2)*sizeof(int));
  • for (i=0;i<l1;i++)
  • b1[i]=false;
  • for (i=0;i<l2;i++)
  • b2[i]=false;
  • for (i=0;i<l1;i++)
  • {
  • for (j=max(i-ecartMax,0);j<=min(i+ecartMax,l2);j++)
  • {
  • if (t1[i]==t2[j])
  • {
  • b1[i]=true; //Indique qu'on a bien trouvé ce caractère
  • b2[j]=true;
  • compteMatching++; //Incrémente le nombre de caractères correspondants
  • break;
  • }
  • }
  • }
  • if (compteMatching==0)
  • return 0.0;
  • t1Matche=TrouverMatches(t1,b1); //Génére la liste des caractères communs dans l'ordre de t1
  • t2Matche=TrouverMatches(t2,b2);
  • compteTransposition=0;
  • if (strcmp(t1Matche,t2Matche)!=0)
  • {
  • for (i=0;i<strlen(t1Matche);i++)
  • if (t1Matche[i]!=t2Matche[i])
  • compteTransposition++; //Calcul le nombre de transpositions
  • }
  • else
  • compteTransposition=0;
  • free(t1Matche);
  • free(t2Matche);
  • distanceJaro=(((double)compteMatching/l1)+((double)compteMatching/l2)+((compteMatching-compteTransposition/2.0)/compteMatching))/3.0;
  • longueurPrefix=0;
  • for (i=0;i<min(3,min(l1,l2))+1;i++) //longueur max : 4
  • {
  • if (t1[i]==t2[i])
  • longueurPrefix++;
  • else
  • break;
  • }
  • return distanceJaro+(longueurPrefix*0.1*(1-distanceJaro));
  • }
  • int main ()
  • {
  • char *t1=malloc(256*sizeof(char));
  • char *t2=malloc(256*sizeof(char));
  • strcpy(t1,"MARTHA");
  • strcpy(t2,"MARHTA");
  • printf("distance %s %s : %f\n",t1,t2,JaroWinkler(t1,t2));
  • strcpy(t1,"DWAYNE");
  • strcpy(t2,"DUANE");
  • printf("distance %s %s : %f\n",t1,t2,JaroWinkler(t1,t2));
  • strcpy(t1,"DIXON");
  • strcpy(t2,"DICKSONX");
  • printf("distance %s %s : %f\n",t1,t2,JaroWinkler(t1,t2));
  • return 0;
  • }
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define true 0
#define false 1
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))

char *TrouverMatches(char * txt,int *bl)
{
	int i,j;
	char *res=malloc(256*sizeof(char));
	char ctmp='a';
	for (i=0;i<256;i++)
	{res[i]=0;}
	i=0,j=0;
	while (ctmp!=0)
	{
		ctmp=txt[i];
		if (bl[i]==true)
		{
			res[j]=ctmp;
			j++;
		}
		i++;
	}
	return res;
}


double JaroWinkler(char *t1,char *t2)
{
	int ecartMax,l1,l2,compteMatching,compteTransposition,longueurPrefix,i,j;
	char *t1Matche,*t2Matche;
	int *b1,*b2;
	double distanceJaro;
	if (t1[0]==0 || t2[0]==0)
		return 0.0;
	l1=strlen(t1);
	l2=strlen(t2);
	ecartMax=(max(l1,l2)/2)-1;
	compteMatching=0;
	b1=malloc((l1+2)*sizeof(int));
	b2=malloc((l2+2)*sizeof(int));
	for (i=0;i<l1;i++)
		b1[i]=false;
	for (i=0;i<l2;i++)
		b2[i]=false;

	for (i=0;i<l1;i++)
	{
		for (j=max(i-ecartMax,0);j<=min(i+ecartMax,l2);j++)
		{
			if (t1[i]==t2[j])
			{
				b1[i]=true; //Indique qu'on a bien trouvé ce caractère
				b2[j]=true;
				compteMatching++; //Incrémente le nombre de caractères correspondants
				break;
			}
			
		}
		
	}
	
	if (compteMatching==0)
		return 0.0;
		
	t1Matche=TrouverMatches(t1,b1); //Génére la liste des caractères communs dans l'ordre de t1
	t2Matche=TrouverMatches(t2,b2);
	
	compteTransposition=0;
	if (strcmp(t1Matche,t2Matche)!=0)
	{
		for (i=0;i<strlen(t1Matche);i++)
			if (t1Matche[i]!=t2Matche[i])
				compteTransposition++; //Calcul le nombre de transpositions
	}
	else
		compteTransposition=0;
	
	free(t1Matche);
	free(t2Matche);
	
	distanceJaro=(((double)compteMatching/l1)+((double)compteMatching/l2)+((compteMatching-compteTransposition/2.0)/compteMatching))/3.0;
	
	longueurPrefix=0;
	for (i=0;i<min(3,min(l1,l2))+1;i++) //longueur max : 4
	{
		if (t1[i]==t2[i])
			longueurPrefix++;
		else
			break;
		
	}
	return distanceJaro+(longueurPrefix*0.1*(1-distanceJaro));
}


int main ()
{
char *t1=malloc(256*sizeof(char));
char *t2=malloc(256*sizeof(char));
strcpy(t1,"MARTHA");
strcpy(t2,"MARHTA");
printf("distance %s %s : %f\n",t1,t2,JaroWinkler(t1,t2));
strcpy(t1,"DWAYNE");
strcpy(t2,"DUANE");
printf("distance %s %s : %f\n",t1,t2,JaroWinkler(t1,t2));
strcpy(t1,"DIXON");
strcpy(t2,"DICKSONX");
printf("distance %s %s : %f\n",t1,t2,JaroWinkler(t1,t2));

return 0;
}



 Historique

07 avril 2009 21:26:32 :
-
07 avril 2009 21:29:01 :
-
08 avril 2009 15:00:49 :
Correction de l'algo.
08 avril 2009 15:09:43 :
oublie d'un -1...
08 avril 2009 21:40:41 :
rajout <=

 Sources de la même categorie

Source avec Zip RECHERCHE D'ANNAGRAMMES par Torin
GESTION DE CHAINE DE CARACTÉRE EN C++ AVEC NSTRING par xmustapha
Source avec Zip COMMENTER CODE C <=> ASM (WIN64) par BruNews
Source avec Zip GSTRING - GESTION DES CHAINES DE CARACTÈRES par Neokript
Source avec Zip ANALYSEUR SYNTAXIQUEV(0.1) par kohan95

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture MOUSE-O-METER par gbourgeois0019
Source avec Zip Source avec une capture SCREENSHOOT A DISTANCE par LeColonel
Source avec Zip DISTANCE PARCOURRUE PAR LA SOURIS (WIN32, HOOK) par ymca2003

Commentaires et avis

Commentaire de pgl10 le 08/04/2009 14:27:18

J'ai quelques soucis avec ce programme.
A la place de : if (&t1[i]==&t1[j])
j'aurais bien vu : if (t1[i]==t2[j])
De plus la ligne : distanceJaro=(double)...
comporte des divisions entières.
Mais 4/8 vaut 0 et non pas 0.5 !
Il manque les #include et un main.
Cela peut donc s'améliorer.

Commentaire de PoulpHunter le 08/04/2009 15:12:53

oups désolé j'avais pas testé mon code !
J'ai corrigé aussi le calcul du nombre de transposition et libération de la mémoire quand on en a plus besoin.

Je n'avais pas mis d'include ni de main pour poster seulement un algorithme pas un programme !
j'ai tout de même rajouté un main de test de la fonction.

Commentaire de pgl10 le 08/04/2009 21:33:11

Maintenant c'est beaucoup mieux. Les 3 exemples de Wikipedia sont bien évalués comme il faut. Mais si on ajoute le calcul de la distance entre "AAA" et "AAA" on trouve : 0 ! On s'attend à : 1, je crois. Est-ce ma compilation qui est en défaut ?

Commentaire de PoulpHunter le 08/04/2009 22:08:19

nan pas d'erreur de compilation
y'avais une erreur de <= à corriger, décidément !
les mots de 1 caractères sont tout de même pas pris en compte (d'après le jaro winkler officiel)

Sinon tu peux jouer sur les paramètres de la boucle for (j...
par exemple de j=0;j<l2;j++
cela permettra de vérifier tout les caractères (et marchera pour les mots de 1 lettre)
mais c'est plus le Jaro-Winkler officiel.
A mon avis on pourrais mettre un plus grand écart de recherche (quand même pas de 0 à l2) cela permettrait de meilleurs résultats.
Il y a aussi l'importance que l'on accorde au préfixe, ici 0.1 qui peut être modifié, par contre ici je penses c'est une bonne valeur.

Je sais pas si tu connais des textes ou l'ordre des lettres est inversé, tant que la première et la dernière lettre sont corrects et que le mot reste un anagramme alors le cerveau arrive à le comprendre sans problème, en se basant sur ce principe (pour la correction orthographique) pourquoi ne pas accorder aussi une importance au suffixe ?
Je penses un préfix max de 4 lettres coeff 0.1 et suffixe max 2 lettres coeff 0.08 est un assez bon réglage.
Enfin sa peut faire l'objet d'une autre source (ou en complément de celle-ci) je vais voir.

Merci pour tes tests en tout cas !

Commentaire de pgl10 le 08/04/2009 23:06:02

C'est bien maintenant. Merci pour les corrections et pour les remarques et variantes éventuelles qui peuvent effectivement être utilisées.

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Récupere le contenu d'un txt à distance via http [ par noplay ] Je veux ouvrir une url (style http://www.hello.com/world.txt) et récuperer le contenu de cette page, ce code doit être portable puisque il sera compil administration a distance [ par roverkiller ] je cherche deux prog ou pluto deux sources en C (1 serveur et un client) pour une administrationa distance, lire des fichiers, lé modifié et pouvoir Controle à distance [ par Belt ] Salut à tous, je suis en train de créer une appli permettant de controller un pc à distance, la souris c bon, le clavier aussi mé pour voir lécran j'u eteindre ordi à distance [ par morgandetoi06 ] voila j aimerait savoir comment faire un programme qui se lance au demarage et qui permet avec un client de donner l ordre a l ordi de s eteindre ( en cin zapé .? [ par morgandetoi06 ] je capte pas, y a des cin&gt;&gt; qui sont zapés quand j execute ????#include &lt;stdlib.h&gt;#include &lt;iostream&gt;using namespace std;int main(vo Peut on ouvrir un fichier à distance ?!? [ par LiBe444 ] Cette question est bête mais j'aimerais savoir si on peut affecter à un handle la valeur FILE* hFile=fopen("http://www.example.com/truc","r");ou si c' Executer un programme a distance [ par Lord_Did ] Bonjour, Est-ce que c'est possible ( en cpp ), d'executer un programme a distance sur un autre poste ? J'ai besoin d'executer un programme qui me se algorithme vecteur à distance [ par dado1984 ] j ai bezsoin d'une application c realise l'algo vecteur à distance connecter a un serveur a distance (urgent!!!!!!) [ par elfiosi ] salut a tous, j'utilise la fonction mysql_real_connect sur visual C++ 6.0 pour acceder a une base de donnee a distance. Est ce que ca requiert une in OpenGl distance de vue [ par fireuo ] Bonjour je vien de commencer l'openGL et que commence a importer des 'Mess' dans mes projets. J'ai aussi rencontr&#233; un probl&#232;me que je ne sui


Nos sponsors


Sondage...

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,718 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales