@@ -135,22 +135,38 @@ extension Trie {
135
135
}
136
136
return currentNode. isTerminating
137
137
}
138
-
138
+
139
+
140
+ /// Attempts to walk to the last node of a word. The
141
+ /// search will fail if the word is not present. Doesn't
142
+ /// check if the node is terminating
143
+ ///
144
+ /// - Parameter word: the word in question
145
+ /// - Returns: the node where the search ended, nil if the
146
+ /// search failed.
147
+ private func findLastNodeOf( word: String ) -> Node ? {
148
+ var currentNode = root
149
+ for character in word. lowercased ( ) . characters {
150
+ guard let childNode = currentNode. children [ character] else {
151
+ return nil
152
+ }
153
+ currentNode = childNode
154
+ }
155
+ return currentNode
156
+ }
157
+
139
158
/// Attempts to walk to the terminating node of a word. The
140
159
/// search will fail if the word is not present.
141
160
///
142
161
/// - Parameter word: the word in question
143
162
/// - Returns: the node where the search ended, nil if the
144
163
/// search failed.
145
164
private func findTerminalNodeOf( word: String ) -> Node ? {
146
- var currentNode = root
147
- for character in word. lowercased ( ) . characters {
148
- guard let childNode = currentNode. children [ character] else {
149
- return nil
150
- }
151
- currentNode = childNode
165
+ if let lastNode = findLastNodeOf ( word: word) {
166
+ return lastNode. isTerminating ? lastNode : nil
152
167
}
153
- return currentNode. isTerminating ? currentNode : nil
168
+ return nil
169
+
154
170
}
155
171
156
172
/// Deletes a word from the trie by starting with the last letter
@@ -201,7 +217,7 @@ extension Trie {
201
217
/// - rootNode: the root node of the subtrie
202
218
/// - partialWord: the letters collected by traversing to this node
203
219
/// - Returns: the words in the subtrie
204
- func wordsInSubtrie( rootNode: Node , partialWord: String ) -> [ String ] {
220
+ fileprivate func wordsInSubtrie( rootNode: Node , partialWord: String ) -> [ String ] {
205
221
var subtrieWords = [ String] ( )
206
222
var previousLetters = partialWord
207
223
if let value = rootNode. value {
@@ -216,4 +232,25 @@ extension Trie {
216
232
}
217
233
return subtrieWords
218
234
}
235
+
236
+ /// Returns an array of words in a subtrie of the trie that start
237
+ /// with given prefix
238
+ ///
239
+ /// - Parameters:
240
+ /// - prefix: the letters for word prefix
241
+ /// - Returns: the words in the subtrie that start with prefix
242
+ func findWordsWithPrefix( prefix: String ) -> [ String ] {
243
+ var words = [ String] ( )
244
+ let prefixLowerCased = prefix. lowercased ( )
245
+ if let lastNode = findLastNodeOf ( word: prefixLowerCased) {
246
+ if lastNode. isTerminating {
247
+ words. append ( prefixLowerCased)
248
+ }
249
+ for childNode in lastNode. children. values {
250
+ let childWords = wordsInSubtrie ( rootNode: childNode, partialWord: prefixLowerCased)
251
+ words += childWords
252
+ }
253
+ }
254
+ return words
255
+ }
219
256
}
0 commit comments