-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrie.go
150 lines (108 loc) · 2.24 KB
/
trie.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package gotri
var (
suggestionList = []string{}
)
type Trie struct {
Children [512]*Trie
isWord bool
Value string
}
func New() *Trie {
t := &Trie{}
t.isWord = false
return t
}
func (t *Trie) Add(s string, value string) {
if len(s) < 1 {
t.isWord = true
t.Value = value
return
}
letter := s[0]
index := letter
if t.Children[index] == nil {
t.Children[index] = New()
}
t.Children[index].Add(s[1:], value)
}
func (t *Trie) Search(keyword string) (string, bool) {
if t == nil {
return "", false
}
curr := t
for i := 0; i < len(keyword); i++ {
letter := keyword[i]
index := letter
curr = curr.Children[index]
if curr == nil {
return "", false
}
}
return curr.Value, curr.isWord
}
//no node has value
//basically end of the node
func isLastNode(t *Trie) bool {
for i := 0; i < 512; i++ {
if t.Children[i] != nil {
return false
}
}
return true
}
//TODO return the value to make it testable
func (t *Trie) GetSuggestion(query string, total int) []string {
var result []string
//move to next position node from the searching character
for i := 0; i < len(query); i++ {
index := query[i]
if t.Children[index] == nil {
return result
}
t = t.Children[index]
}
//it's a word and has no child node
//return the search keyword in the array
if t.isWord && isLastNode(t) {
result = append(result, query)
return result
}
wordList := []string{}
//check if the searching word already is a word
//tappend if true
if t.isWord {
wordList = append(wordList, query)
total--
}
if !isLastNode(t) {
_, result = Suggestion(t, query, wordList, total)
}
return result
}
func Suggestion(t *Trie, prefix string, wordList []string, repeat int) (int, []string) {
if isLastNode(t) {
if t.isWord && len(wordList) < 1 {
wordList = append(wordList, prefix)
}
return repeat, wordList
}
for i := 0; i < 512; i++ {
if repeat < 1 {
return repeat, wordList
}
r := t
if t.Children[i] != nil {
l := i
prefix += string(l)
r = r.Children[i]
if r.isWord {
wordList = append(wordList, prefix)
repeat--
}
repeat, wordList = Suggestion(r, prefix, wordList, repeat)
// fmt.Println(prefix)
prefix = prefix[0 : len(prefix)-1]
}
}
return repeat, wordList
}