Skip to content

Instantly share code, notes, and snippets.

@andybons
Created September 17, 2012 14:59
Show Gist options
  • Save andybons/3737860 to your computer and use it in GitHub Desktop.
Save andybons/3737860 to your computer and use it in GitHub Desktop.
Case-insensitive Levenshtein Distance Implementation
// runeAt returns the unicode rune at the specified index.
func runeAt(s string, index int) rune {
i := 0
for _, c := range s {
if i == index {
return c
}
i++
}
return -1
}
// compare returns the edit distance between two given strings
// using a modified, case-insensitive version of the Levenshtein
// distance algorithm.
func compare(a, b string) int {
a = strings.ToLower(a)
b = strings.ToLower(b)
a_len := utf8.RuneCountInString(a)
b_len := utf8.RuneCountInString(b)
d := make([][]int, a_len+1)
for i := 0; i < len(d); i++ {
d[i] = make([]int, b_len+1)
}
for i := 0; i < len(d); i++ {
d[i][0] = i
}
for i := 0; i < len(d[0]); i++ {
d[0][i] = i
}
for i := 1; i < len(d); i++ {
for j := 1; j < len(d[0]); j++ {
if runeAt(a, i-1) == runeAt(b, j-1) {
d[i][j] = d[i-1][j-1]
} else if i > 1 && j > 1 && runeAt(a, i-1) == runeAt(b, j-2) && runeAt(a, i-2) == runeAt(b, j-1) {
min1 := d[i-2][j-2] + 1
min2 := d[i-1][j] + 1
min3 := d[i][j-1] + 1
min4 := d[i-1][j-1] + 1
d[i][j] = int(math.Min(math.Min(float64(min1), float64(min2)), math.Min(float64(min3), float64(min4))))
} else {
min1 := d[i-1][j] + 1
min2 := d[i][j-1] + 1
min3 := d[i-1][j-1] + 1
d[i][j] = int(math.Min(math.Min(float64(min1), float64(min2)), float64(min3)))
}
}
}
return d[a_len][b_len]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment