-
Notifications
You must be signed in to change notification settings - Fork 0
/
trie.go
75 lines (63 loc) · 1.3 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
package purify
import (
"errors"
)
var (
// ErrDuplicateWord returns a soft error indicating a word's duplicate status
ErrDuplicateWord = errors.New("word already exist")
)
// Trie implements the data structure of same name
type Trie struct {
End bool
ChildTries []Dict
}
// NewTrie returns a new Trie object
func NewTrie() *Trie {
return &Trie{
End: false,
ChildTries: make([]Dict, 0),
}
}
// Find returns true if a given word exists in the word map or false otherwise
func (t *Trie) Find(word string) bool {
subTrie := t
for _, r := range word {
trie, ok := subTrie.value(r)
if !ok {
return false // not found
}
subTrie = trie
}
return subTrie.End
}
// AddWord adds a new distinct word to the trie
func (t *Trie) AddWord(word string) error {
if ok := t.Find(word); ok {
return ErrDuplicateWord
}
subTrie := t
for _, r := range word {
trie, ok := subTrie.value(r)
if !ok {
trie = new(Trie)
trie.ChildTries = make([]Dict, 0)
subTrie.ChildTries = append(subTrie.ChildTries, Dict{
Key: r,
Value: trie,
})
}
subTrie = trie
}
if !subTrie.End {
subTrie.End = true
}
return nil
}
func (t *Trie) value(r rune) (*Trie, bool) {
for _, child := range t.ChildTries {
if child.Key == r {
return child.Value, true
}
}
return nil, false
}