1package smetrics 2 3import ( 4 "math" 5) 6 7func Jaro(a, b string) float64 { 8 la := float64(len(a)) 9 lb := float64(len(b)) 10 11 // match range = max(len(a), len(b)) / 2 - 1 12 matchRange := int(math.Floor(math.Max(la, lb)/2.0)) - 1 13 matchRange = int(math.Max(0, float64(matchRange-1))) 14 var matches, halfs float64 15 transposed := make([]bool, len(b)) 16 17 for i := 0; i < len(a); i++ { 18 start := int(math.Max(0, float64(i-matchRange))) 19 end := int(math.Min(lb-1, float64(i+matchRange))) 20 21 for j := start; j <= end; j++ { 22 if transposed[j] { 23 continue 24 } 25 26 if a[i] == b[j] { 27 if i != j { 28 halfs++ 29 } 30 matches++ 31 transposed[j] = true 32 break 33 } 34 } 35 } 36 37 if matches == 0 { 38 return 0 39 } 40 41 transposes := math.Floor(float64(halfs / 2)) 42 43 return ((matches / la) + (matches / lb) + (matches-transposes)/matches) / 3.0 44} 45