Advertisement
Guest User

Untitled

a guest
Jun 17th, 2017
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ABAP 3.24 KB | None | 0 0
  1. #include <string>
  2. #include <algorithm>
  3. #include <iostream> //~ Pour la démo uniquement
  4.  
  5.  
  6. /*
  7.     ****************************************************************
  8.     Analyse distance d'edition (algorithme de Jaro Winkler).
  9.     Les chaines à comparer sont passées par référence
  10.     ce qui est + rapide et - lourd.
  11.     ****************************************************************
  12. */
  13. float jaroWinkler(const std::string &s1, const std::string &s2)
  14. {
  15.     /********
  16.     Variables
  17.     ********/
  18.  
  19.     //~ Coefficient de winkler, favorise les chaines ayant un début commun.
  20.     const float c_p = 0.25;
  21.    
  22.     //~ Autre coefficient qui vaut le nombre de caractère commun en début de chaine,
  23.     //~ avec une valeur maximale à 4
  24.     unsigned int c_l;
  25.    
  26.     //~ Utile pour ne pas appeler X fois les methodes size()
  27.     const signed int s1size = s1.size(), s2size = s2.size();
  28.    
  29.     //~ Distance std::max pour que deux caractères correspondant mais placés
  30.     //~ à des offsets différents soient considérés comme "matching"
  31.     const float dstMax = (float)std::max(s1size, s2size) / 2.0 - 1.0;
  32.    
  33.     //~ Listes des caracteres "matching"
  34.     std::string s1_match, s2_match;
  35.  
  36.     //~ Nombre de transposition: caractère identique mais pas à la même place
  37.     float t = 0;
  38.    
  39.     //~ Nombre de caractère "matching"
  40.     float m;
  41.    
  42.     //~ Itérateurs
  43.     signed int i, j;
  44.    
  45.     //~ Distances de jaro pour simplifier la formule de jaro-winker
  46.     float dj;
  47.    
  48.    
  49.     /**********
  50.     Algorithme
  51.     **********/
  52.  
  53.     //~ Caracteres identiques et identiquement placés (on se limite à 4)
  54.     for (c_l = 0 ; c_l < std::min(4, std::min(s1size,s2size)) && s1[c_l] == s2[c_l] ; c_l++ ) {}
  55.    
  56.     //~ Recherches des caractères correspondants de s1 dans s2
  57.     //~ -------------------------------------------------------------------------------------
  58.     //~ Pour chaque caractère de s1 à l'offset i, on cherche un caractère identique dans s2
  59.     //~ a l'offset j allant de i-dstMax à i+dstMax
  60.     //~ L'interval i-dstMax I+dstMax n'est pas clairement codé, car c'est plus lent (experimenté).
  61.     //~ mais le principe est là.
  62.     //~ De plus, si un caractère correspond, on l'enregistre dans une liste
  63.     for ( i = 0 ; i < s1size ; i++ )
  64.     {  
  65.         for ( j = 0 ; j < s2size ; j++ )
  66.         {
  67.             if ( std::abs(i-j) <= dstMax && s1[i] == s2[j] )
  68.             {
  69.                 s1_match += s1[i++];   
  70.                 j=0;
  71.             }
  72.         }
  73.     }
  74.    
  75.     //~ Recherche des caractères correspondants de s2 dans s1
  76.     for ( i = 0 ; i < s2size ; i++ )
  77.     {
  78.         for ( j = 0 ; j < s1size ; j++ )
  79.         {
  80.             if ( std::abs(i-j) <= dstMax && s1[j] == s2[i] )
  81.             {
  82.                 s2_match += s2[i++];
  83.                 j=0;
  84.             }
  85.         }
  86.     }
  87.    
  88.     //~ m vaut le nombre de caractère correspondant
  89.     m = std::min(s1_match.size(),s2_match.size());
  90.     if ( m == 0 ) return 0;
  91.    
  92.     //~ Recherche du nombre de transposition, dans les listes de correspondances
  93.     for ( i = 0 ; i < m ; i++ )
  94.     {
  95.         if ( s1_match[i] != s2_match[i] )
  96.         {
  97.             t++;
  98.         }
  99.     }
  100.    
  101.     //~ On divise par deux car une transposition est comptée
  102.     //~ pour l'échange de deux caractères
  103.     t = t / 2.0;
  104.    
  105.     //~ Distance de jaro
  106.     dj = 1.0/3.0 * ( m/s1size + m/s2size + (m-t)/m);
  107.    
  108.     //~ Distance de jaro-winkler
  109.     return dj + (c_l*c_p*(1.0-dj));
  110. }
  111.  
  112.  
  113.  
  114. /*
  115.     démo
  116. */
  117. int main(int argc, char **argv)
  118. {
  119.     if ( argc == 3 )
  120.         std::cout << jaroWinkler(argv[1], argv[2]) << std::endl;
  121. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement