diff --git a/Pod/SwiftyLevenshtein.swift b/Pod/SwiftyLevenshtein.swift new file mode 100644 index 0000000..a4c48db --- /dev/null +++ b/Pod/SwiftyLevenshtein.swift @@ -0,0 +1,244 @@ +// +// SwiftyLevenshtein.swift +// Levenshtein distance algorithm written in Swift 2.2. Both a slow and highly optimized version are included. +// +// Created by Mark Hamilton on 3/31/16. +// Copyright © 2016 dryverless. (http://www.dryverless.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +import Foundation + +// Minimize 3 +public func min3(a: Int, b: Int, c: Int) -> Int { + + return min( min(a, c), min(b, c)) + +} + +// In case they ever let subscripts throw +//public extension String { +// +// internal enum SubscriptError: ErrorType { +// +// case InvalidFirstChar +// +// case InvalidLastChar +// +// } +// +// +// subscript(range: Range) throws -> String { +// +// guard let firstChar = startIndex.advancedBy(range.startIndex) else { +// +// throw SubscriptError.InvalidFirstChar +// } +// +// guard let lastChar = startIndex.advancedBy(range.endIndex) else { +// +// throw SubscriptError.InvalidLastChar +// +// } +// +// return self[firstChar... Character { + + return self[startIndex.advancedBy(index)] + + } + + subscript(range: Range) -> String { + + let char0 = startIndex.advancedBy(range.startIndex) + + let charN = startIndex.advancedBy(range.endIndex) + + return self[char0.. Int { + + get { + + return matrix[columns * row + column] + + } + + set { + + matrix[columns * row + column] = newValue + + } + + } + + func columnCount() -> Int { + + return self.columns + + } + + func rowCount() -> Int { + + return self.rows + + } +} + +/* Levenshtein Distance Algorithm + * Calculates the minimum number of changes (distance) between two strings. + */ + +public func slowlevenshtein(sourceString: String, target targetString: String) -> Int { + + let source = Array(sourceString.unicodeScalars) + let target = Array(targetString.unicodeScalars) + + let (sourceLength, targetLength) = (source.count, target.count) + + var matrix = Array(count: targetLength + 1, repeatedValue: Array(count: sourceLength + 1, repeatedValue: 0)) + + for x in 1.. Int { + + let source = Array(sourceString.unicodeScalars) + let target = Array(targetString.unicodeScalars) + + let (sourceLength, targetLength) = (source.count, target.count) + + var distance = Array2D(columns: sourceLength + 1, rows: targetLength + 1) + + for x in 1...sourceLength { + + distance[x, 0] = x + + } + + for y in 1...targetLength { + + distance[0, y] = y + + } + + for x in 1...sourceLength { + + for y in 1...targetLength { + + if source[x - 1] == target[y - 1] { + + // no difference + distance[x, y] = distance[x - 1, y - 1] + + } else { + + distance[x, y] = min3( + + // deletions + distance[x - 1, y] + 1, + // insertions + b: distance[x, y - 1] + 1, + // substitutions + c: distance[x - 1, y - 1] + 1 + + ) + + } + + } + + } + + return distance[source.count, target.count] + +} + +public extension String { + + func getSlowLevenshtein(target: String) -> Int { + + return slowlevenshtein(self, target: target) + + } + + func getLevenshtein(target: String) -> Int { + + return levenshtein(self, target: target) + + } + +}