@@ -2,380 +2,380 @@ import Foundation
2
2
3
3
// The root is the top of the Radix Tree
4
4
public class Root {
5
- var children : [ Edge ]
6
-
7
- public init ( ) {
8
- children = [ Edge] ( )
9
- }
10
-
11
- // Returns the length (in number of edges) of the longest traversal down the tree.
12
- public func height( ) -> Int {
13
- // Base case: no children: the tree has a height of 1
14
- if children. count == 0 {
15
- return 1
16
- }
17
- // Recursion: find the max height of a root's child and return 1 + that max
18
- else {
19
- var max = 1
20
- for c in children {
21
- if c. height ( ) > max {
22
- max = c. height ( )
23
- }
24
- }
25
- return 1 + max
26
- }
27
- }
28
-
29
- // Returns how far down in the tree a Root/Edge is.
30
- // A root's level is always 0.
31
- public func level( ) -> Int {
32
- return 0
33
- }
34
-
35
- // Prints the tree for debugging/visualization purposes.
36
- public func printRoot( ) {
37
- // Print the first half of the children
38
- if children. count > 1 {
39
- for c in 0 ... children. count/ 2 - 1 {
40
- children [ c] . printEdge ( )
41
- print ( " | " )
42
- }
43
- } else if children. count > 0 {
44
- children [ 0 ] . printEdge ( )
45
- }
46
- // Then print the root
47
- print ( " ROOT " )
48
- // Print the second half of the children
49
- if children. count > 1 {
50
- for c in children. count/ 2 ... children. count- 1 {
51
- children [ c] . printEdge ( )
52
- print ( " | " )
53
- }
54
- }
55
- print ( )
56
- }
5
+ var children : [ Edge ]
6
+
7
+ public init ( ) {
8
+ children = [ Edge] ( )
9
+ }
10
+
11
+ // Returns the length (in number of edges) of the longest traversal down the tree.
12
+ public func height( ) -> Int {
13
+ // Base case: no children: the tree has a height of 1
14
+ if children. count == 0 {
15
+ return 1
16
+ }
17
+ // Recursion: find the max height of a root's child and return 1 + that max
18
+ else {
19
+ var max = 1
20
+ for c in children {
21
+ if c. height ( ) > max {
22
+ max = c. height ( )
23
+ }
24
+ }
25
+ return 1 + max
26
+ }
27
+ }
28
+
29
+ // Returns how far down in the tree a Root/Edge is.
30
+ // A root's level is always 0.
31
+ public func level( ) -> Int {
32
+ return 0
33
+ }
34
+
35
+ // Prints the tree for debugging/visualization purposes.
36
+ public func printRoot( ) {
37
+ // Print the first half of the children
38
+ if children. count > 1 {
39
+ for c in 0 ... children. count/ 2 - 1 {
40
+ children [ c] . printEdge ( )
41
+ print ( " | " )
42
+ }
43
+ } else if children. count > 0 {
44
+ children [ 0 ] . printEdge ( )
45
+ }
46
+ // Then print the root
47
+ print ( " ROOT " )
48
+ // Print the second half of the children
49
+ if children. count > 1 {
50
+ for c in children. count/ 2 ... children. count- 1 {
51
+ children [ c] . printEdge ( )
52
+ print ( " | " )
53
+ }
54
+ }
55
+ print ( )
56
+ }
57
57
}
58
58
59
59
// Edges are what actually store the Strings in the tree
60
60
public class Edge : Root {
61
- var parent : Root ?
62
- var label : String
63
-
64
- public init ( _ label: String ) {
65
- self . label = label
66
- super. init ( )
67
- }
68
-
69
- public override func level( ) -> Int {
70
- // Recurse up the tree incrementing level by one until the root is reached
71
- if parent != nil {
72
- return 1 + parent!. level ( )
73
- }
74
- // If an edge has no parent, it's level is one
75
- // NOTE: THIS SHOULD NEVER HAPPEN AS THE ROOT IS ALWAYS THE TOP OF THE TREE
76
- else {
77
- return 1
78
- }
79
- }
80
-
81
- // Erases a specific edge (and all edges below it in the tree).
82
- public func erase( ) {
83
- self . parent = nil
84
- if children. count > 0 {
85
- // For each child, erase it, then remove it from the children array.
86
- for _ in 0 ... children. count- 1 {
87
- children [ 0 ] . erase ( )
88
- children. removeAtIndex ( 0 )
89
- }
90
- }
91
- }
92
-
93
- // Prints the tree for debugging/visualization purposes.
94
- public func printEdge( ) {
95
- // Print the first half of the edge's children
96
- if children. count > 1 {
97
- for c in 0 ... children. count/ 2 - 1 {
98
- children [ c] . printEdge ( )
99
- }
100
- } else if children. count > 0 {
101
- children [ 0 ] . printEdge ( )
102
- }
103
- // Tab over once up to the edge's level
104
- for x in 1 ... level ( ) {
105
- if x == level ( ) {
106
- print ( " |------> " , terminator: " " )
107
- } else {
108
- print ( " | " , terminator: " " )
109
- }
110
- }
111
- print ( label)
112
- // Print the second half of the edge's children
113
- if children. count == 0 {
114
- for _ in 1 ... level ( ) {
115
- print ( " | " , terminator: " " )
116
- }
117
- print ( )
118
- }
119
- if children. count > 1 {
120
- for c in children. count/ 2 ... children. count- 1 {
121
- children [ c] . printEdge ( )
122
- }
123
- }
124
- }
61
+ var parent : Root ?
62
+ var label : String
63
+
64
+ public init ( _ label: String ) {
65
+ self . label = label
66
+ super. init ( )
67
+ }
68
+
69
+ public override func level( ) -> Int {
70
+ // Recurse up the tree incrementing level by one until the root is reached
71
+ if parent != nil {
72
+ return 1 + parent!. level ( )
73
+ }
74
+ // If an edge has no parent, it's level is one
75
+ // NOTE: THIS SHOULD NEVER HAPPEN AS THE ROOT IS ALWAYS THE TOP OF THE TREE
76
+ else {
77
+ return 1
78
+ }
79
+ }
80
+
81
+ // Erases a specific edge (and all edges below it in the tree).
82
+ public func erase( ) {
83
+ self . parent = nil
84
+ if children. count > 0 {
85
+ // For each child, erase it, then remove it from the children array.
86
+ for _ in 0 ... children. count- 1 {
87
+ children [ 0 ] . erase ( )
88
+ children. remove ( at : 0 )
89
+ }
90
+ }
91
+ }
92
+
93
+ // Prints the tree for debugging/visualization purposes.
94
+ public func printEdge( ) {
95
+ // Print the first half of the edge's children
96
+ if children. count > 1 {
97
+ for c in 0 ... children. count/ 2 - 1 {
98
+ children [ c] . printEdge ( )
99
+ }
100
+ } else if children. count > 0 {
101
+ children [ 0 ] . printEdge ( )
102
+ }
103
+ // Tab over once up to the edge's level
104
+ for x in 1 ... level ( ) {
105
+ if x == level ( ) {
106
+ print ( " |------> " , terminator: " " )
107
+ } else {
108
+ print ( " | " , terminator: " " )
109
+ }
110
+ }
111
+ print ( label)
112
+ // Print the second half of the edge's children
113
+ if children. count == 0 {
114
+ for _ in 1 ... level ( ) {
115
+ print ( " | " , terminator: " " )
116
+ }
117
+ print ( )
118
+ }
119
+ if children. count > 1 {
120
+ for c in children. count/ 2 ... children. count- 1 {
121
+ children [ c] . printEdge ( )
122
+ }
123
+ }
124
+ }
125
125
}
126
126
127
127
public class RadixTree {
128
- var root : Root
129
-
130
- public init ( ) {
131
- root = Root ( )
132
- }
133
-
134
- // Returns the height of the tree by calling the root's height function.
135
- public func height( ) -> Int {
136
- return root. height ( ) - 1
137
- }
138
-
139
- // Inserts a string into the tree.
140
- public func insert( str: String ) -> Bool {
141
- //Account for a blank input. The empty string is already in the tree.
142
- if str == " " {
143
- return false
144
- }
145
-
146
- // searchStr is the parameter of the function
147
- // it will be substringed as the function traverses down the tree
148
- var searchStr = str
149
-
150
- // currEdge is the current Edge (or Root) in question
151
- var currEdge = root
152
-
153
- while true {
154
- var found = false
155
-
156
- // If the current Edge has no children then the remaining searchStr is
157
- // created as a child
158
- if currEdge. children. count == 0 {
159
- let newEdge = Edge ( searchStr)
160
- currEdge. children. append ( newEdge)
161
- newEdge. parent = currEdge
162
- return true
163
- }
164
-
165
- // Loop through all of the children
166
- for e in currEdge. children {
167
- // Get the shared prefix between the child in question and the
168
- // search string
169
- let shared = sharedPrefix ( searchStr, e. label)
170
- var index = shared. startIndex
171
-
172
- // If the search string is equal to the shared string,
173
- // the string already exists in the tree
174
- if searchStr == shared {
175
- return false
176
- }
177
-
178
- // If the child's label is equal to the shared string, you have to
179
- // traverse another level down the tree, so substring the search
180
- // string, break the loop, and run it back
181
- else if shared == e. label {
182
- currEdge = e
183
- var tempIndex = searchStr. startIndex
184
- for _ in 1 ... shared. characters. count {
185
- tempIndex = tempIndex . successor ( )
186
- }
187
- searchStr = searchStr. substringFromIndex ( tempIndex)
188
- found = true
189
- break
190
- }
191
-
192
- // If the child's label and the search string share a partial prefix,
193
- // then both the label and the search string need to be substringed
194
- // and a new branch needs to be created
195
- else if shared. characters. count > 0 {
196
- var labelIndex = e. label. characters. startIndex
197
-
198
- // Create index objects and move them to after the shared prefix
199
- for _ in 1 ... shared. characters. count {
200
- index = index . successor ( )
201
- labelIndex = labelIndex . successor ( )
202
- }
203
-
204
- // Substring both the search string and the label from the shared prefix
205
- searchStr = searchStr. substringFromIndex ( index)
206
- e. label = e. label. substringFromIndex ( labelIndex)
207
-
208
- // Create 2 new edges and update parent/children values
209
- let newEdge = Edge ( e. label)
210
- e. label = shared
211
- for ec in e. children {
212
- newEdge. children. append ( ec)
213
- }
214
- newEdge. parent = e
215
- e. children. removeAll ( )
216
- for nec in newEdge. children {
217
- nec. parent = newEdge
218
- }
219
- e. children. append ( newEdge)
220
- let newEdge2 = Edge ( searchStr)
221
- newEdge2. parent = e
222
- e. children. append ( newEdge2)
223
- return true
224
- }
225
- // If they don't share a prefix, go to next child
226
- }
227
-
228
- // If none of the children share a prefix, you have to create a new child
229
- if !found {
230
- let newEdge = Edge ( searchStr)
231
- currEdge. children. append ( newEdge)
232
- newEdge. parent = currEdge
233
- return true
234
- }
235
- }
236
- }
237
-
238
- // Tells you if a string is in the tree
239
- public func find( str: String ) -> Bool {
240
- // A radix tree always contains the empty string
241
- if str == " " {
242
- return true
243
- }
244
- // If there are no children then the string cannot be in the tree
245
- else if root. children. count == 0 {
246
- return false
247
- }
248
- var searchStr = str
249
- var currEdge = root
250
- while true {
251
- var found = false
252
- // Loop through currEdge's children
253
- for c in currEdge. children {
254
- // First check if the search string and the child's label are equal
255
- // if so the string is in the tree, return true
256
- if searchStr == c. label {
257
- return true
258
- }
259
-
260
- // If that is not true, find the shared string b/t the search string
261
- // and the label
262
- let shared = sharedPrefix ( searchStr, c. label)
263
-
264
- // If the shared string is equal to the label, update the curent node,
265
- // break the loop, and run it back
266
- if shared == c. label {
267
- currEdge = c
268
- var tempIndex = searchStr. startIndex
269
- for _ in 1 ... shared. characters. count {
270
- tempIndex = tempIndex . successor ( )
271
- }
272
- searchStr = searchStr. substringFromIndex ( tempIndex)
273
- found = true
274
- break
275
- }
276
-
277
- // If the shared string is empty, go to the next child
278
- else if shared. characters. count == 0 {
279
- continue
280
- }
281
-
282
- // If the shared string matches the search string, return true
283
- else if shared == searchStr {
284
- return true
285
- }
286
-
287
- // If the search string and the child's label only share some characters,
288
- // the string is not in the tree, return false
289
- else if shared [ shared. startIndex] == c. label [ c. label. startIndex] &&
290
- shared. characters. count < c. label. characters. count {
291
- return false
292
- }
293
- }
294
-
295
- // If nothing was found, return false
296
- if !found {
297
- return false
298
- }
299
- }
300
- }
301
-
302
- // Removes a string from the tree
303
- public func remove( str: String ) -> Bool {
304
- // Removing the empty string removes everything in the tree
305
- if str == " " {
306
- for c in root. children {
307
- c. erase ( )
308
- root. children. removeAtIndex ( 0 )
309
- }
310
- return true
311
- }
312
- // If the tree is empty, you cannot remove anything
313
- else if root. children. count == 0 {
314
- return false
315
- }
316
-
317
- var searchStr = str
318
- var currEdge = root
319
- while true {
320
- var found = false
321
- // If currEdge has no children, then the searchStr is not in the tree
322
- if currEdge. children. count == 0 {
323
- return false
324
- }
325
-
326
- // Loop through the children
327
- for c in 0 ... currEdge. children. count- 1 {
328
- // If the child's label matches the search string, remove that child
329
- // and everything below it in the tree
330
- if currEdge. children [ c] . label == searchStr {
331
- currEdge. children [ c] . erase ( )
332
- currEdge. children. removeAtIndex ( c)
333
- return true
334
- }
335
-
336
- // Find the shared string
337
- let shared = sharedPrefix ( searchStr, currEdge. children [ c] . label)
338
-
339
- // If the shared string is equal to the child's string, go down a level
340
- if shared == currEdge. children [ c] . label {
341
- currEdge = currEdge. children [ c]
342
- var tempIndex = searchStr. startIndex
343
- for _ in 1 ... shared. characters. count {
344
- tempIndex = tempIndex . successor ( )
345
- }
346
- searchStr = searchStr. substringFromIndex ( tempIndex)
347
- found = true
348
- break
349
- }
350
- }
351
-
352
- // If there is no match, then the searchStr is not in the tree
353
- if !found {
354
- return false
355
- }
356
- }
357
- }
358
-
359
- // Prints the tree by calling the root's print function
360
- public func printTree( ) {
361
- root. printRoot ( )
362
- }
128
+ var root : Root
129
+
130
+ public init ( ) {
131
+ root = Root ( )
132
+ }
133
+
134
+ // Returns the height of the tree by calling the root's height function.
135
+ public func height( ) -> Int {
136
+ return root. height ( ) - 1
137
+ }
138
+
139
+ // Inserts a string into the tree.
140
+ public func insert( _ str: String ) -> Bool {
141
+ //Account for a blank input. The empty string is already in the tree.
142
+ if str == " " {
143
+ return false
144
+ }
145
+
146
+ // searchStr is the parameter of the function
147
+ // it will be substringed as the function traverses down the tree
148
+ var searchStr = str
149
+
150
+ // currEdge is the current Edge (or Root) in question
151
+ var currEdge = root
152
+
153
+ while true {
154
+ var found = false
155
+
156
+ // If the current Edge has no children then the remaining searchStr is
157
+ // created as a child
158
+ if currEdge. children. count == 0 {
159
+ let newEdge = Edge ( searchStr)
160
+ currEdge. children. append ( newEdge)
161
+ newEdge. parent = currEdge
162
+ return true
163
+ }
164
+
165
+ // Loop through all of the children
166
+ for e in currEdge. children {
167
+ // Get the shared prefix between the child in question and the
168
+ // search string
169
+ let shared = sharedPrefix ( searchStr, e. label)
170
+ var index = shared. startIndex
171
+
172
+ // If the search string is equal to the shared string,
173
+ // the string already exists in the tree
174
+ if searchStr == shared {
175
+ return false
176
+ }
177
+
178
+ // If the child's label is equal to the shared string, you have to
179
+ // traverse another level down the tree, so substring the search
180
+ // string, break the loop, and run it back
181
+ else if shared == e. label {
182
+ currEdge = e
183
+ var tempIndex = searchStr. startIndex
184
+ for _ in 1 ... shared. characters. count {
185
+ tempIndex = searchStr . characters . index ( after : tempIndex )
186
+ }
187
+ searchStr = searchStr. substring ( from : tempIndex)
188
+ found = true
189
+ break
190
+ }
191
+
192
+ // If the child's label and the search string share a partial prefix,
193
+ // then both the label and the search string need to be substringed
194
+ // and a new branch needs to be created
195
+ else if shared. characters. count > 0 {
196
+ var labelIndex = e. label. characters. startIndex
197
+
198
+ // Create index objects and move them to after the shared prefix
199
+ for _ in 1 ... shared. characters. count {
200
+ index = searchStr . characters . index ( after : index )
201
+ labelIndex = e . label . characters . index ( after : labelIndex )
202
+ }
203
+
204
+ // Substring both the search string and the label from the shared prefix
205
+ searchStr = searchStr. substring ( from : index)
206
+ e. label = e. label. substring ( from : labelIndex)
207
+
208
+ // Create 2 new edges and update parent/children values
209
+ let newEdge = Edge ( e. label)
210
+ e. label = shared
211
+ for ec in e. children {
212
+ newEdge. children. append ( ec)
213
+ }
214
+ newEdge. parent = e
215
+ e. children. removeAll ( )
216
+ for nec in newEdge. children {
217
+ nec. parent = newEdge
218
+ }
219
+ e. children. append ( newEdge)
220
+ let newEdge2 = Edge ( searchStr)
221
+ newEdge2. parent = e
222
+ e. children. append ( newEdge2)
223
+ return true
224
+ }
225
+ // If they don't share a prefix, go to next child
226
+ }
227
+
228
+ // If none of the children share a prefix, you have to create a new child
229
+ if !found {
230
+ let newEdge = Edge ( searchStr)
231
+ currEdge. children. append ( newEdge)
232
+ newEdge. parent = currEdge
233
+ return true
234
+ }
235
+ }
236
+ }
237
+
238
+ // Tells you if a string is in the tree
239
+ public func find( _ str: String ) -> Bool {
240
+ // A radix tree always contains the empty string
241
+ if str == " " {
242
+ return true
243
+ }
244
+ // If there are no children then the string cannot be in the tree
245
+ else if root. children. count == 0 {
246
+ return false
247
+ }
248
+ var searchStr = str
249
+ var currEdge = root
250
+ while true {
251
+ var found = false
252
+ // Loop through currEdge's children
253
+ for c in currEdge. children {
254
+ // First check if the search string and the child's label are equal
255
+ // if so the string is in the tree, return true
256
+ if searchStr == c. label {
257
+ return true
258
+ }
259
+
260
+ // If that is not true, find the shared string b/t the search string
261
+ // and the label
262
+ let shared = sharedPrefix ( searchStr, c. label)
263
+
264
+ // If the shared string is equal to the label, update the curent node,
265
+ // break the loop, and run it back
266
+ if shared == c. label {
267
+ currEdge = c
268
+ var tempIndex = searchStr. startIndex
269
+ for _ in 1 ... shared. characters. count {
270
+ tempIndex = searchStr . characters . index ( after : tempIndex )
271
+ }
272
+ searchStr = searchStr. substring ( from : tempIndex)
273
+ found = true
274
+ break
275
+ }
276
+
277
+ // If the shared string is empty, go to the next child
278
+ else if shared. characters. count == 0 {
279
+ continue
280
+ }
281
+
282
+ // If the shared string matches the search string, return true
283
+ else if shared == searchStr {
284
+ return true
285
+ }
286
+
287
+ // If the search string and the child's label only share some characters,
288
+ // the string is not in the tree, return false
289
+ else if shared [ shared. startIndex] == c. label [ c. label. startIndex] &&
290
+ shared. characters. count < c. label. characters. count {
291
+ return false
292
+ }
293
+ }
294
+
295
+ // If nothing was found, return false
296
+ if !found {
297
+ return false
298
+ }
299
+ }
300
+ }
301
+
302
+ // Removes a string from the tree
303
+ public func remove( _ str: String ) -> Bool {
304
+ // Removing the empty string removes everything in the tree
305
+ if str == " " {
306
+ for c in root. children {
307
+ c. erase ( )
308
+ root. children. remove ( at : 0 )
309
+ }
310
+ return true
311
+ }
312
+ // If the tree is empty, you cannot remove anything
313
+ else if root. children. count == 0 {
314
+ return false
315
+ }
316
+
317
+ var searchStr = str
318
+ var currEdge = root
319
+ while true {
320
+ var found = false
321
+ // If currEdge has no children, then the searchStr is not in the tree
322
+ if currEdge. children. count == 0 {
323
+ return false
324
+ }
325
+
326
+ // Loop through the children
327
+ for c in 0 ... currEdge. children. count- 1 {
328
+ // If the child's label matches the search string, remove that child
329
+ // and everything below it in the tree
330
+ if currEdge. children [ c] . label == searchStr {
331
+ currEdge. children [ c] . erase ( )
332
+ currEdge. children. remove ( at : c)
333
+ return true
334
+ }
335
+
336
+ // Find the shared string
337
+ let shared = sharedPrefix ( searchStr, currEdge. children [ c] . label)
338
+
339
+ // If the shared string is equal to the child's string, go down a level
340
+ if shared == currEdge. children [ c] . label {
341
+ currEdge = currEdge. children [ c]
342
+ var tempIndex = searchStr. startIndex
343
+ for _ in 1 ... shared. characters. count {
344
+ tempIndex = searchStr . characters . index ( after : tempIndex )
345
+ }
346
+ searchStr = searchStr. substring ( from : tempIndex)
347
+ found = true
348
+ break
349
+ }
350
+ }
351
+
352
+ // If there is no match, then the searchStr is not in the tree
353
+ if !found {
354
+ return false
355
+ }
356
+ }
357
+ }
358
+
359
+ // Prints the tree by calling the root's print function
360
+ public func printTree( ) {
361
+ root. printRoot ( )
362
+ }
363
363
}
364
364
365
365
// Returns the prefix that is shared between the two input strings
366
366
// i.e. sharedPrefix("court", "coral") -> "co"
367
- public func sharedPrefix( str1: String , _ str2: String ) -> String {
368
- var temp = " "
369
- var c1 = str1. characters. startIndex
370
- var c2 = str2. characters. startIndex
371
- for _ in 0 ... min ( str1. characters. count- 1 , str2. characters. count- 1 ) {
372
- if str1 [ c1] == str2 [ c2] {
373
- temp. append ( str1 [ c1] )
374
- c1 = c1 . successor ( )
375
- c2 = c2 . successor ( )
376
- } else {
377
- return temp
378
- }
379
- }
380
- return temp
367
+ public func sharedPrefix( _ str1: String , _ str2: String ) -> String {
368
+ var temp = " "
369
+ var c1 = str1. characters. startIndex
370
+ var c2 = str2. characters. startIndex
371
+ for _ in 0 ... min ( str1. characters. count- 1 , str2. characters. count- 1 ) {
372
+ if str1 [ c1] == str2 [ c2] {
373
+ temp. append ( str1 [ c1] )
374
+ c1 = str1 . characters . index ( after : c1 )
375
+ c2 = str2 . characters . index ( after : c2 )
376
+ } else {
377
+ return temp
378
+ }
379
+ }
380
+ return temp
381
381
}
0 commit comments