The Jaro distance is a measure of edit distance between two strings; its inverse, called the Jaro similarity, is a measure of two strings' similarity: the higher the value, the more similar the strings are. The score is normalized such that   0   equates to no similarities and   1   is an exact match.



Definition
The Jaro similarity   




d

j




{\displaystyle d_{j}}

   of two given strings   




s

1




{\displaystyle s_{1}}

   and   




s

2




{\displaystyle s_{2}}

   is

 




d

j


=

{




0



if 

m
=
0






1
3



(


m


|


s

1



|




+


m


|


s

2



|




+



m
−
t

m


)




otherwise









{\displaystyle d_{j}=\left\{{\begin{array}{l l}0&{\text{if }}m=0\\{\frac {1}{3}}\left({\frac {m}{|s_{1}|}}+{\frac {m}{|s_{2}|}}+{\frac {m-t}{m}}\right)&{\text{otherwise}}\end{array}}\right.}


Where:

 



m


{\displaystyle m}

   is the number of matching characters;
 



t


{\displaystyle t}

   is half the number of transpositions.


Two characters from   




s

1




{\displaystyle s_{1}}

   and   




s

2




{\displaystyle s_{2}}

   respectively, are considered matching only if they are the same and not farther apart than   




⌊



max
(

|


s

1



|

,

|


s

2



|

)

2


⌋

−
1


{\displaystyle \left\lfloor {\frac {\max(|s_{1}|,|s_{2}|)}{2}}\right\rfloor -1}

 characters.

Each character of   




s

1




{\displaystyle s_{1}}

   is compared with all its matching characters in   




s

2




{\displaystyle s_{2}}

. Each difference in position is half a transposition; that is, the number of transpositions is half the number of characters which are common to the two strings but occupy different positions in each one.



Example
Given the strings   




s

1




{\displaystyle s_{1}}

   DWAYNE   and   




s

2




{\displaystyle s_{2}}

   DUANE   we find:

 



m
=
4


{\displaystyle m=4}


 




|


s

1



|

=
6


{\displaystyle |s_{1}|=6}


 




|


s

2



|

=
5


{\displaystyle |s_{2}|=5}


 



t
=
0


{\displaystyle t=0}




We find a Jaro score of:

 




d

j


=


1
3



(


4
6


+


4
5


+



4
−
0

4


)

=
0.822


{\displaystyle d_{j}={\frac {1}{3}}\left({\frac {4}{6}}+{\frac {4}{5}}+{\frac {4-0}{4}}\right)=0.822}




Task
Implement the Jaro algorithm and show the similarity scores for each of the following pairs:

 ("MARTHA", "MARHTA")
 ("DIXON", "DICKSONX")
 ("JELLYFISH", "SMELLYFISH")


 See also
 Jaro–Winkler distance on Wikipedia.


' version 09-10-2016
' compile with: fbc -s console
 
#Macro max(x, y)
  IIf((x) > (y), (x), (y))
#EndMacro
 
#Macro min(x, y)
  IIf((x) < (y), (x), (y))
#EndMacro
 
Function jaro(word1 As String, word2 As String) As Double
 
  If Len(word1) > Len(word2) Then Swap word1, word2
 
  Dim As Long i, j, j1, m, t
  Dim As Long s1 = Len(word1)
  Dim As Long s2 = Len(word2)
  Dim As Long max_dist = s2 \ 2 -1  ' integer division
 
  For i = 0 To s1 -1 
    If word1[i] = word2[j] Then
      m = m +1
      word2[j] = 32
    Else
      For j1 = max(0, i - max_dist) To min(s2 -1, i + max_dist)
        If word1[i] = word2[j1] Then
          t = t +1
          m = m +1
          word2[j1] = 32
         If j1 > j Then j = j1
        End If
      Next
    End If
    j = j + 1
  Next
 
  If m = 0 Then Return 0
 
  t = t \ 2
  Return (m / s1 + m / s2 + ((m - t) / m)) / 3
 
End Function
 
' ------=< MAIN >=------
 
Print
Print " jaro (MARTHA,    MARHTA)     ="; jaro("MARTHA", "MARHTA")
Print " jaro (DIXON,     DICKSONX)   ="; jaro("DIXON", "DICKSONX")
Print " jaro (JELLYFISH, SMELLYFISH) ="; jaro("JELLYFISH", "SMELLYFISH")
 
 
' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End