2017-05-21 60 views
1

我使用Rosetta Code的教程来计算Levenshtein距离。看起来他们的代码是在Swift2中,所以我在执行此操作时得到这个错误Binary operator '+' cannot be applied to operands of type '[Int]' and 'Repeated<String.CharacterView>'var cur = [i + 2] + empty其中let empty = repeatElement(s, count: 0)。我怎么去解决这个问题?Swift3中的Levenshtein距离

+1

不是直接回答你的问题,但在这里http://stackoverflow.com/questions/26990394/slow-swift-arrays-and-strings-performance是应该需要斯威夫特稍作修改的实施3. –

+0

感谢,工作,但仍然喜欢使用他们的(罗塞塔)方法,因为它看起来更短。 – styl3r

回答

4

做了一些改变。

  • 数组的构造为空。
  • 枚举()现在枚举()
  • 继任者(),所以我用+1

取代它不存在了这样的功能,现在是

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! 
} 
0

更新和改进回答Swift 4,基于@Spads回答。

func levenshteinDistanceScoreTo(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 Float.leastNormalMagnitude 
}