-
Notifications
You must be signed in to change notification settings - Fork 0
/
trie_mo.go
121 lines (105 loc) · 2.46 KB
/
trie_mo.go
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package trietst
// TrieMO can be the root, and can be a sub-tree
type TrieMO struct {
Val interface{}
lessChildren []lessChildrenItem
moreChildren map[byte]*TrieMO
//children map[byte]*TrieMO
}
type lessChildrenItem struct {
key byte
st *TrieMO
}
// Child returns the child subtree of the current tree
func (t *TrieMO) Child(c byte) *TrieMO {
if t.moreChildren == nil {
// find child in lessChildren
for _, child := range t.lessChildren {
if child.key == c {
return child.st
}
}
if len(t.lessChildren) < 8 {
child := &TrieMO{}
t.lessChildren = append(t.lessChildren, lessChildrenItem{c, child})
return child
}
// can not find children in lessChildren, we convert lessChildren to moreChildren
t.moreChildren = map[byte]*TrieMO{}
for _, child := range t.lessChildren {
t.moreChildren[child.key] = child.st
}
t.lessChildren = nil
}
child := t.moreChildren[c]
if child == nil {
child = &TrieMO{}
t.moreChildren[c] = child
}
return child
}
//func (t *TrieMO) Child(c byte) *TrieMO {
// if t.children == nil {
// t.children = map[byte]*TrieMO{}
// }
//
// child := t.children[c]
// if child == nil {
// child = &TrieMO{}
// t.children[c] = child
// }
// return child
//}
// Set sets the value of string in the current tree
func (t *TrieMO) Set(s string, val interface{}) {
t.set(s, val, 0)
}
func (t *TrieMO) set(s string, val interface{}, idx int) {
if idx < len(s) {
t.Child(s[idx]).set(s, val, idx+1)
} else {
t.Val = val
}
}
// Get returns the value of string in the current tree
func (t *TrieMO) Get(s string) (val interface{}) {
return t.get(s, 0)
}
func (t *TrieMO) get(s string, idx int) (val interface{}) {
if idx < len(s) {
return t.Child(s[idx]).get(s, idx+1)
} else {
return t.Val
}
}
// Sub returns the subtree of the current tree with specified prefix
func (t *TrieMO) Sub(s string) *TrieMO {
return t.sub(s, 0)
}
func (t *TrieMO) sub(s string, idx int) *TrieMO {
if idx < len(s) {
return t.Child(s[idx]).sub(s, idx+1)
} else {
return t
}
}
func (t *TrieMO) ForEach(f func(s string, val interface{})) {
var prefix []byte
t.forEach(f, prefix)
}
func (t *TrieMO) forEach(f func(s string, val interface{}), prefix []byte) {
if t.Val != nil {
f(string(prefix), t.Val)
}
if t.moreChildren == nil {
for _, lc := range t.lessChildren {
lc.st.forEach(f, append(prefix, lc.key))
}
} else {
for c, st := range t.moreChildren {
if st != nil {
st.forEach(f, append(prefix, c))
}
}
}
}