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