use Damerau-Levenshtein distance

Former-commit-id: 073f2be728690d9ef8662bb9960b91424694d12d [formerly 073f2be728690d9ef8662bb9960b91424694d12d [formerly f9f4e84e4d4b771b0eb9d7a9965bf8d7d246e91a [formerly c913a0221468ea66309d376cd7aa6e5ee94eefbe]]]
Former-commit-id: b65b58d2e287b62da016134632cd51281d4fafc3
Former-commit-id: a33c88925474e837abe5061fbd4a7930879f7230 [formerly 2905c2ed4801d650acd6f94261c553a33f2cfc80]
Former-commit-id: 5a892a6304228629f31bd7f10040f1b2150d5ddb
pull/15/head
Miguel Mota 6 years ago
parent 2c59ad0957
commit c13e7586d8

@ -104,8 +104,8 @@ Key|Action
<kbd>Space</kbd>|Alias to enter key
<kbd>Ctrl</kbd>+<kbd>c</kbd>|Alias to quit
<kbd>Ctrl</kbd>+<kbd>d</kbd>|Jump page down (vim style)
<kbd>Ctrl</kbd>+<kbd>n</kbd>|Go to next page (vim style)
<kbd>Ctrl</kbd>+<kbd>p</kbd>|Go to previous page (vim style)
<kbd>Ctrl</kbd>+<kbd>n</kbd>|Go to next page
<kbd>Ctrl</kbd>+<kbd>p</kbd>|Go to previous page
<kbd>Ctrl</kbd>+<kbd>r</kbd>|Force refresh
<kbd>Ctrl</kbd>+<kbd>u</kbd>|Jump page up (vim style)
<kbd>Alt</kbd>+<kbd></kbd>|Sort current column in ascending order

@ -59,7 +59,7 @@ func (ct *Cointop) search(q string) error {
return nil
}
// store index with the smallest levenshtein
dist := levenshtein.Distance(name, q)
dist := levenshtein.DamerauLevenshteinDistance(name, q)
if min == -1 || dist <= min {
idx = i
min = dist

@ -1,5 +1,10 @@
package levenshtein
import (
"math"
"strings"
)
// Distance Levenshtein distance
// The Levenshtein distance between two strings is defined as the minimum
// number of edits needed to transform one string into the other, with the
@ -43,15 +48,51 @@ func Distance(str1, str2 string) int {
return column[lenS1]
}
func min(a, b, c int) int {
if a < b {
if a < c {
return a
// DamerauLevenshteinDistance calculates the damerau-levenshtein distance between s1 and s2.
// Reference: [Damerau-Levenshtein Distance](http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance)
// Note that this calculation's result isn't normalized. (not between 0 and 1.)
// and if s1 and s2 are exactly the same, the result is 0.
func DamerauLevenshteinDistance(s1, s2 string) int {
if s1 == s2 {
return 0
}
s1Array := strings.Split(s1, "")
s2Array := strings.Split(s2, "")
lenS1Array := len(s1Array)
lenS2Array := len(s2Array)
m := make([][]int, lenS1Array+1)
var cost int
for i := range m {
m[i] = make([]int, lenS2Array+1)
}
for i := 0; i < lenS1Array+1; i++ {
for j := 0; j < lenS2Array+1; j++ {
if i == 0 {
m[i][j] = j
} else if j == 0 {
m[i][j] = i
} else {
cost = 0
if s1Array[i-1] != s2Array[j-1] {
cost = 1
}
m[i][j] = min(m[i-1][j]+1, m[i][j-1]+1, m[i-1][j-1]+cost)
if i > 1 && j > 1 && s1Array[i-1] == s2Array[j-2] && s1Array[i-2] == s2Array[j-1] {
m[i][j] = min(m[i][j], m[i-2][j-2]+cost)
}
}
}
} else {
if b < c {
return b
}
return m[lenS1Array][lenS2Array]
}
// min returns the minimum number of passed int slices.
func min(is ...int) int {
min := int(math.MaxInt64)
for _, v := range is {
if min > v {
min = v
}
}
return c
return min
}

Loading…
Cancel
Save