Skip to content

Commit 8fd553b

Browse files
committed
Update index.go
1 parent a06bd33 commit 8fd553b

File tree

1 file changed

+85
-24
lines changed

1 file changed

+85
-24
lines changed

implement-trie-prefix-tree/index.go

Lines changed: 85 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,104 @@
11
package implement_trie_prefix_tree
22

33
type Trie struct {
4-
children [26]*Trie
5-
isEnd bool
4+
Prefix string
5+
IsEnd bool
6+
Children map[string]*Trie
7+
words map[string]bool
68
}
79

810
func Constructor() Trie {
9-
return Trie{}
11+
return Trie{
12+
words: make(map[string]bool),
13+
14+
Children: make(map[string]*Trie)}
1015
}
1116

1217
func (t *Trie) Insert(word string) {
13-
node := t
14-
for _, ch := range word {
15-
ch -= 'a'
16-
if node.children[ch] == nil {
17-
node.children[ch] = &Trie{}
18-
}
19-
node = node.children[ch]
18+
t.words[word] = true
19+
if t.Prefix == "" && !t.IsEnd {
20+
t.Prefix = word
21+
t.IsEnd = true
22+
return
23+
}
24+
if t.Prefix == word {
25+
t.IsEnd = true
26+
return
27+
}
28+
prefixLen := CommonPrefixLen(t.Prefix, word)
29+
if len(t.Prefix) > prefixLen {
30+
t.split(prefixLen)
2031
}
21-
node.isEnd = true
22-
}
2332

24-
func (t *Trie) SearchPrefix(prefix string) *Trie {
25-
node := t
26-
for _, ch := range prefix {
27-
ch -= 'a'
28-
if node.children[ch] == nil {
29-
return nil
30-
}
31-
node = node.children[ch]
33+
if len(word) > prefixLen {
34+
kid := t.findOrCreateKid(word[prefixLen : prefixLen+1])
35+
kid.Insert(word[prefixLen+1:])
36+
} else {
37+
t.IsEnd = true
3238
}
33-
return node
39+
}
40+
func (node *Trie) findOrCreateKid(char string) *Trie {
41+
kid, ok := node.Children[char]
42+
if ok {
43+
return kid
44+
}
45+
kidn := Constructor()
46+
47+
node.Children[char] = &kidn
48+
return &kidn
49+
}
50+
func (node *Trie) split(n int) {
51+
52+
node.Children = map[string]*Trie{}
53+
var kidn = Constructor()
54+
var ntn = &kidn
55+
ntn.Prefix = node.Prefix[n+1:]
56+
ntn.Children = node.Children
57+
ntn.IsEnd = node.IsEnd
58+
node.Children[node.Prefix[n:n+1]] = ntn
59+
node.Prefix = node.Prefix[:n]
60+
node.IsEnd = false
61+
3462
}
3563

3664
func (t *Trie) Search(word string) bool {
37-
node := t.SearchPrefix(word)
38-
return node != nil && node.isEnd
65+
return t.words[word]
3966
}
4067

4168
func (t *Trie) StartsWith(prefix string) bool {
42-
return t.SearchPrefix(prefix) != nil
69+
var has = t.words[prefix]
70+
if has {
71+
return true
72+
}
73+
// fmt.Println(t.Prefix,t.IsEnd,t.Children,t.words)
74+
// fmt.Println(prefix)
75+
if len(prefix) == 0 {
76+
return true
77+
}
78+
if t.Prefix == prefix {
79+
return true
80+
}
81+
82+
n := CommonPrefixLen(t.Prefix, prefix)
83+
if n == len(t.Prefix) {
84+
kid, found := t.Children[prefix[n:n+1]]
85+
if found {
86+
return kid.StartsWith(prefix[n+1:])
87+
88+
}
89+
}
90+
if n == len(prefix) {
91+
return true
92+
}
93+
return false
94+
}
95+
func CommonPrefixLen(s1, s2 string) int {
96+
n1, n2 := len(s1), len(s2)
97+
i := 0
98+
for ; i < n1 && i < n2; i++ {
99+
if s1[i] != s2[i] {
100+
break
101+
}
102+
}
103+
return i
43104
}

0 commit comments

Comments
 (0)