forked from gracelang/minigrace
-
Notifications
You must be signed in to change notification settings - Fork 3
/
prefixTree.grace
62 lines (54 loc) · 1.71 KB
/
prefixTree.grace
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
dialect "standard"
// Implements a prefix tree, also known as a trie. Maintains a prefix-closed
// set of sequences.
//
// If [a, b, c] is already in the trie, it is considered to also contain
// all prefixes, i.e., [], [a] and [a, b], even though it has size 1
// The empty prefix tree contains the empty sequence.
def end = object {
inherit singleton "end"
method size { 1 }
method at(_)ifAbsent(anAction) { anAction.apply }
method add(entry) index (ix) { prefixTree.add(entry) index(ix) }
}
class prefixTree {
// answers an empty prefix tree
def dict = dictionary.empty
method add (entry:Collection) {
add (entry) index 1
}
method empty { outer.prefixTree }
method with (entry) { outer.prefixTree.add(entry) }
method withAll (entries) {
def result = outer.prefixTree
entries.do { each -> result.add(each) }
result
}
method add(entry) index (ix) {
if (ix > entry.size) then { return }
def first = entry.at(ix)
var value := dict.at(first) ifAbsent {
if (entry.size == ix) then { end } else { prefixTree }
}
if (entry.size > ix) then {
value := value.add (entry) index (ix + 1)
}
dict.at(first) put(value)
self
}
method contains (entry:Collection) → Boolean {
var currentDict := dict
entry.keysAndValuesDo { ix, next →
currentDict := currentDict.at(next) ifAbsent { return false }
}
true
}
method size {
var count := 0
dict.valuesDo { v → count := count + v.size }
count
}
method at(key) ifAbsent (action) {
dict.at(key) ifAbsent (action)
}
}