2017-05-21 96 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 
}