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 }