-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathlevenshtein.go
50 lines (45 loc) · 1.46 KB
/
levenshtein.go
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
45
46
47
48
49
50
package stringosim
import ()
type LevenshteinSimilarityOptions struct {
InsertCost int
DeleteCost int
SubstituteCost int
CaseInsensitive bool
}
var DefaultLevenshteinSimilarityOptions = LevenshteinSimilarityOptions{
InsertCost: 1,
DeleteCost: 1,
SubstituteCost: 1,
}
func Levenshtein(s []rune, t []rune, options ...LevenshteinSimilarityOptions) int {
changeCost := DefaultLevenshteinSimilarityOptions.SubstituteCost
deleteCost := DefaultLevenshteinSimilarityOptions.DeleteCost
insertCost := DefaultLevenshteinSimilarityOptions.InsertCost
caseInsensitive := DefaultLevenshteinSimilarityOptions.CaseInsensitive
if len(options) > 0 {
for _, option := range options {
changeCost = option.SubstituteCost
insertCost = option.InsertCost
deleteCost = option.DeleteCost
caseInsensitive = option.CaseInsensitive
break
}
}
d := make([]int, len(t)+1)
for i := 0; i <= len(t); i++ {
d[i] = i * insertCost
}
for is, cs := range s {
tmpD := d[0]
d[0] = (is + 1) * deleteCost
for it, ct := range t {
curChangeCost := changeCost
if SameRune(cs, ct, caseInsensitive) {
curChangeCost = 0
}
nextD := Min(Min(d[it+1]+deleteCost, d[it]+insertCost), tmpD+curChangeCost)
tmpD, d[it+1] = d[it+1], nextD
}
}
return d[len(t)]
}