Swift Levenshtein距离(以迅捷3为单位)

Swift Levenshtein距离(以迅捷3为单位),swift,swift3,levenshtein-distance,rosetta-code,Swift,Swift3,Levenshtein Distance,Rosetta Code,我正在使用来自的教程来计算Levenshtein距离。看起来他们的代码是Swift2,所以我得到了这个错误执行此操作时,二进制运算符“+”不能应用于“[Int]”和“Repeated”类型的操作数:var cur=[I+2]+empty其中let empty=repeatedelement(s,count:0)。我怎样才能做到这一点呢?需要做一些更改 数组的构造为空 enumerate()现在是enumerated() 继任者()已不存在,因此我将其替换为+1 所以函数现在是 Swift 4

我正在使用来自的教程来计算Levenshtein距离。看起来他们的代码是Swift2,所以我得到了这个错误
执行此操作时,二进制运算符“+”不能应用于“[Int]”和“Repeated”类型的操作数:
var cur=[I+2]+empty
其中
let empty=repeatedelement(s,count:0)
。我怎样才能做到这一点呢?

需要做一些更改

  • 数组的构造为空
  • enumerate()现在是enumerated()
  • 继任者()已不存在,因此我将其替换为+1
所以函数现在是

Swift 4:

func levDis(_ w1: String, _ w2: String) -> Int {
    let empty = [Int](repeating:0, count: w2.count)
    var last = [Int](0...w2.count)

    for (i, char1) in w1.enumerated() {
        var cur = [i + 1] + empty
        for (j, char2) in w2.enumerated() {
            cur[j + 1] = char1 == char2 ? last[j] : min(last[j], last[j + 1], cur[j]) + 1
        }
        last = cur
    }
    return last.last!
}
func levDis(w1: String, w2: String) -> Int {

    let (t, s) = (w1.characters, w2.characters)

    let empty = Array<Int>(repeating:0, count: s.count)
    var last = [Int](0...s.count)

    for (i, tLett) in t.enumerated() {
        var cur = [i + 1] + empty
        for (j, sLett) in s.enumerated() {
            cur[j + 1] = tLett == sLett ? last[j] : min(last[j], last[j + 1], cur[j])+1
        }
        last = cur
    }
    return last.last!
}
Swift 3:

func levDis(_ w1: String, _ w2: String) -> Int {
    let empty = [Int](repeating:0, count: w2.count)
    var last = [Int](0...w2.count)

    for (i, char1) in w1.enumerated() {
        var cur = [i + 1] + empty
        for (j, char2) in w2.enumerated() {
            cur[j + 1] = char1 == char2 ? last[j] : min(last[j], last[j + 1], cur[j]) + 1
        }
        last = cur
    }
    return last.last!
}
func levDis(w1: String, w2: String) -> Int {

    let (t, s) = (w1.characters, w2.characters)

    let empty = Array<Int>(repeating:0, count: s.count)
    var last = [Int](0...s.count)

    for (i, tLett) in t.enumerated() {
        var cur = [i + 1] + empty
        for (j, sLett) in s.enumerated() {
            cur[j + 1] = tLett == sLett ? last[j] : min(last[j], last[j + 1], cur[j])+1
        }
        last = cur
    }
    return last.last!
}
func-levDis(w1:String,w2:String)->Int{
设(t,s)=(w1个字符,w2个字符)
let empty=数组(重复:0,计数:s.count)
var last=[Int](0…s.count)
对于t.枚举()中的(i,ttlett){
变量cur=[i+1]+空
对于s.枚举()中的(j,sLett){
cur[j+1]=tLett==sLett?last[j]:min(last[j],last[j+1],cur[j])+1
}
last=cur
}
最后一个,最后一个!
}

根据@Spads-answer更新并改进了Swift 4的答案

extension String {
    func levenshteinDistanceScore(to string: String, ignoreCase: Bool = true, trimWhiteSpacesAndNewLines: Bool = true) -> Float {

        var firstString = self
        var secondString = string   

        if ignoreCase {
            firstString = firstString.lowercased()
            secondString = secondString.lowercased()
        }
        if trimWhiteSpacesAndNewLines {
            firstString = firstString.trimmingCharacters(in: .whitespacesAndNewlines)
            secondString = secondString.trimmingCharacters(in: .whitespacesAndNewlines)
        }

        let empty = [Int](repeating:0, count: secondString.count)
        var last = [Int](0...secondString.count)

        for (i, tLett) in firstString.enumerated() {
            var cur = [i + 1] + empty
            for (j, sLett) in secondString.enumerated() {
                cur[j + 1] = tLett == sLett ? last[j] : Swift.min(last[j], last[j + 1], cur[j])+1
            }
            last = cur
        }

        // maximum string length between the two
        let lowestScore = max(firstString.count, secondString.count)

        if let validDistance = last.last {
            return  1 - (Float(validDistance) / Float(lowestScore))
        }

        return 0.0
    }
}

infix operator =~
func =~(string: String, otherString: String) -> Bool {
    return string.levenshteinDistanceScore(to: otherString) >= 0.85
}

由于@Daniel Illescas的答案不起作用,这里是使用
Int
返回类型和assert的工作版本

extension String {

    func levenshteinDistance(to string: String, ignoreCase: Bool = true, trimWhiteSpacesAndNewLines: Bool = true) -> Int {
        
        var firstString = self
        var secondString = string
        
        if ignoreCase {
            firstString = firstString.lowercased()
            secondString = secondString.lowercased()
        }
        
        if trimWhiteSpacesAndNewLines {
            firstString = firstString.trimmingCharacters(in: .whitespacesAndNewlines)
            secondString = secondString.trimmingCharacters(in: .whitespacesAndNewlines)
        }
        
        let empty = [Int](repeating: 0, count: secondString.count)
        var last = [Int](0...secondString.count)
        
        for (i, tLett) in firstString.enumerated() {
            var cur = [i + 1] + empty
            for (j, sLett) in secondString.enumerated() {
                cur[j + 1] = tLett == sLett ? last[j] : Swift.min(last[j], last[j + 1], cur[j]) + 1
            }
            
            last = cur
        }
        
        if let validDistance = last.last {
            return validDistance
        }
        
        assertionFailure()
        return 0
    }
}

这不是对您的问题的直接回答,但是这里有一个实现,它应该只需要对Swift 3进行一些小的修改。谢谢,已经完成了,但仍然希望使用他们的(Rosetta)方法,因为它看起来更短。这是LevenshTeInstancesCore字符串扩展的正确运算符重载。这算什么?据我所知,Levenshtein距离是一个Int,而不是一个float。这对我来说也没有意义。IDK如果它仍然有效,但基本上它应该返回一个介于0a和1之间的值,0表示字符串完全不同,1表示字符串相同;它返回两个字符串的相似程度。