storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/words/damerau-levenshtein.go (about)

     1  /*
     2   * MinIO Client (C) 2014, 2015, 2016, 2017 MinIO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package words
    18  
    19  import "math"
    20  
    21  // Returns the minimum value of a slice of integers
    22  func minimum(integers []int) (minVal int) {
    23  	minVal = math.MaxInt32
    24  	for _, v := range integers {
    25  		if v < minVal {
    26  			minVal = v
    27  		}
    28  	}
    29  	return
    30  }
    31  
    32  // DamerauLevenshteinDistance calculates distance between two strings using an algorithm
    33  // described in https://en.wikipedia.org/wiki/Damerau-Levenshtein_distance
    34  func DamerauLevenshteinDistance(a string, b string) int {
    35  	var cost int
    36  	d := make([][]int, len(a)+1)
    37  	for i := 1; i <= len(a)+1; i++ {
    38  		d[i-1] = make([]int, len(b)+1)
    39  	}
    40  	for i := 0; i <= len(a); i++ {
    41  		d[i][0] = i
    42  	}
    43  	for j := 0; j <= len(b); j++ {
    44  		d[0][j] = j
    45  	}
    46  	for i := 1; i <= len(a); i++ {
    47  		for j := 1; j <= len(b); j++ {
    48  			if a[i-1] == b[j-1] {
    49  				cost = 0
    50  			} else {
    51  				cost = 1
    52  			}
    53  			d[i][j] = minimum([]int{
    54  				d[i-1][j] + 1,
    55  				d[i][j-1] + 1,
    56  				d[i-1][j-1] + cost,
    57  			})
    58  			if i > 1 && j > 1 && a[i-1] == b[j-2] && a[i-2] == b[j-1] {
    59  				d[i][j] = minimum([]int{d[i][j], d[i-2][j-2] + cost}) // transposition
    60  			}
    61  		}
    62  	}
    63  	return d[len(a)][len(b)]
    64  }