我构建了一个如下所示的trie数据结构:
struct Trie<Element : Hashable> : Equatable {
private var children: [Element: Trie<Element>]
private var endHere: Bool
}
对来自UITextField
的输入执行自动更正操作。我给trie提供了各种功能,例如insert:
/**
Private insert function. Inserts an elements into a trie using a sequences' generator.
- parameter g: `GeneratorType`.
*/
private mutating func insert<G: GeneratorType where G.Element == Element>(g: G) {
var gen = g
if let head = gen.next() {
if case nil = children[head]?.insert(gen) {
children[head] = Trie(g: gen)
}
} else {
endHere = true
}
}
/**
Insert elements into the trie.
- parameter seq: Sequence of elements.
*/
mutating func insert<S: SequenceType where S.Generator.Element == Element>(seq: S) {
insert(seq.generate())
}
必要的初始化程序:
/**
Create an empty trie.
*/
init() {
children = [:]
endHere = false
}
/**
Initialize a trie with a generator.
- parameter g: `GeneratorType`.
*/
private init<G: GeneratorType where G.Element == Element>(g: G) {
var gen = g
if let head = gen.next() {
(children, endHere) = ([head:Trie(g: gen)], false)
} else {
(children, endHere) = ([:], true)
}
}
/**
Construct from an arbitrary sequence of sequences with elements of type `Element`.
- parameter s: Sequence of sequences.
*/
init<S: SequenceType, Inner: SequenceType where S.Generator.Element == Inner, Inner.Generator.Element == Element>(_ s: S) {
self.init()
s.forEach { insert($0) }
}
/**
Construct a trie from a sequence of elements.
- parameter s: Sequence.
*/
init <S: SequenceType where S.Generator.Element == Element>(_ s: S) {
self.init(g: s.generate())
}
并且Trie
符合SequenceType
,以便我可以遍历这些元素。
现在,我想实现一个levenshtein距离搜索,其搜索功能如下:
func search<S: SequenceType where S.Generator.Element == Element(s: S, maxDistance: Int = 0) -> [(S, Int)] {
}
其中返回值是找到的匹配子序列的列表,以及距离原始查询序列的最大距离,但这是我的知识有点缺乏的地方。我不确定如何在计算插入,删除和重置成本的同时实际执行搜索并建立匹配序列列表。
答案 0 :(得分:1)
对此的解决方案并不重要,但请查看论文Fast String Correction with Levenshtein-Automata。你会把你的特里视为字典自动机,它与Levenshtein自动机相交。搜索策略用于仅跟踪交叉点上的路径,这些路径导致与Levenshtein距离(来自查询项)的项不超过指定的阈值。
作为参考,liblevenshtein具有Java实现。有关搜索特里结构的逻辑,请查看src/main/java/com/github/liblevenshtein/transducer。