github.com/maresnic/mr-kong@v1.0.0/levenshtein.go (about)

     1  package kong
     2  
     3  import "unicode/utf8"
     4  
     5  // https://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#Go
     6  // License: https://creativecommons.org/licenses/by-sa/3.0/
     7  func levenshtein(a, b string) int {
     8  	f := make([]int, utf8.RuneCountInString(b)+1)
     9  
    10  	for j := range f {
    11  		f[j] = j
    12  	}
    13  
    14  	for _, ca := range a {
    15  		j := 1
    16  		fj1 := f[0] // fj1 is the value of f[j - 1] in last iteration
    17  		f[0]++
    18  		for _, cb := range b {
    19  			mn := min(f[j]+1, f[j-1]+1) // delete & insert
    20  			if cb != ca {
    21  				mn = min(mn, fj1+1) // change
    22  			} else {
    23  				mn = min(mn, fj1) // matched
    24  			}
    25  
    26  			fj1, f[j] = f[j], mn // save f[j] to fj1(j is about to increase), update f[j] to mn
    27  			j++
    28  		}
    29  	}
    30  
    31  	return f[len(f)-1]
    32  }
    33  
    34  func min(a, b int) int {
    35  	if a <= b {
    36  		return a
    37  	}
    38  	return b
    39  }