@@ -23,33 +23,45 @@ let jaro (s1: string) (s2: string) =
2323let matchRadius =
2424let minLen = Math.Min( s1.Length, s2.Length)
2525 minLen/ 2 + minLen% 2
26-
27- // An inner function which recursively finds the number
28- // of matched characters within the radius.
29- let commonChars ( chars1 : string ) ( chars2 : string ) =
30- let result = ResizeArray( chars1.Length)
31- for i= 0 to chars1.Length- 1 do
32- let c = chars1.[ i]
33- if existsInWin c chars2 i matchRadiusthen
34- result.Add c
35- result
36-
37- // The sets of common characters and their lengths as floats
38- let c1 = commonChars s1 s2
39- let c2 = commonChars s2 s1
40- let c1length = float c1.Count
41- let c2length = float c2.Count
42-
26+
27+ let rec nextChar ( s1 : string ) ( s2 : string ) i c =
28+ if i< s1.Lengththen
29+ let c = s1.[ i]
30+ if not ( existsInWin c s2 i matchRadius) then
31+ nextChar s1 s2( i+ 1 ) c
32+ else
33+ struct ( i, c)
34+ else
35+ struct ( i, c)
36+
37+ // The sets of common characters and their lengths as floats
4338// The number of transpositions within the sets of common characters.
44- let transpositions =
45- let mutable mismatches = 0.0
46- for i= 0 to ( Math.Min( c1.Count, c2.Count)) - 1 do
47- if c1.[ i] <> c2.[ i] then
48- mismatches<- mismatches+ 1.0
49-
50- // If one common string is longer than the other
51- // each additional char counts as half a transposition
52- ( mismatches+ abs( c1length- c2length)) / 2.0
39+ let struct ( transpositions , c1length , c2length ) =
40+ let rec loop i j mismatches c1length c2length =
41+ if i< s1.Length&& j< s2.Lengththen
42+ let struct ( ti , ci ) = nextChar s1 s2 i' '
43+ let struct ( tj , cj ) = nextChar s2 s1 j' '
44+ if ci<> cjthen
45+ loop( ti+ 1 ) ( tj+ 1 ) ( mismatches+ 1 ) ( c1length+ 1 ) ( c2length+ 1 )
46+ else
47+ loop( ti+ 1 ) ( tj+ 1 ) mismatches( c1length+ 1 ) ( c2length+ 1 )
48+ else struct ( i, j, mismatches, c1length, c2length)
49+
50+ let struct ( i , j , mismatches , c1length , c2length ) = loop0 0 0 0 0
51+
52+ let rec loop ( s1 : string ) ( s2 : string ) i length =
53+ if i< s1.Length- 1 then
54+ let c = s1.[ i]
55+ if existsInWin c s2 i matchRadiusthen
56+ loop s1 s2( i+ 1 ) ( length+ 1 )
57+ else
58+ loop s1 s2( i+ 1 ) length
59+ else
60+ length
61+ let c1length = loop s1 s2 i c1length|> float
62+ let c2length = loop s2 s1 j c2length|> float
63+
64+ struct (( float mismatches+ abs( c1length- c2length)) / 2.0 , c1length, c2length)
5365
5466let tLength = Math.Max( c1length, c2length)
5567