File tree Expand file tree Collapse file tree 3 files changed +177
-0
lines changed
geeksforgeeks/auto-complete-feature Expand file tree Collapse file tree 3 files changed +177
-0
lines changed Original file line number Diff line number Diff line change
1
+ # Auto-complete feature
2
+
3
+ We are given a Trie with a set of strings stored in it.
4
+ Now the user types in a prefix of his search query,
5
+ we need to give him all recommendations to auto-complete his query based on the strings stored in the Trie.
6
+
7
+ ## Copyright Notice
8
+
9
+ This problem is based on [ content] ( https://www.geeksforgeeks.org/auto-complete-feature-using-trie/ )
10
+ from [ GeeksforGeeks] ( https://www.geeksforgeeks.org )
11
+ written by Hemang Sarkar
12
+ and subject to [ GeeksforGeeks copyright] ( https://www.geeksforgeeks.org/legal/copyright-information/ ) .
13
+ The original content from GeeksforGeeks and any modifications made here are attributed to GeeksforGeeks contributors,
14
+ and this work is shared under [ CC BY-SA 4.0] ( ../LICENSE ) .
Original file line number Diff line number Diff line change
1
+ package auto_complete_feature
2
+
3
+ const alphabetSize = 26 + 1
4
+
5
+ func Solution (q string , dict []string ) []string {
6
+ if q == "" {
7
+ return nil
8
+ }
9
+
10
+ root := newTrieNode ()
11
+ for _ , word := range dict {
12
+ root .insert (word )
13
+ }
14
+
15
+ return root .autoComplete (q )
16
+ }
17
+
18
+ type trieNode struct {
19
+ childs []* trieNode
20
+ isWord bool
21
+ isLeaf bool
22
+ }
23
+
24
+ func newTrieNode () * trieNode {
25
+ return & trieNode {
26
+ childs : make ([]* trieNode , alphabetSize ),
27
+ }
28
+ }
29
+
30
+ func (node * trieNode ) insert (s string ) {
31
+ if len (s ) == 0 {
32
+ node .isLeaf = true
33
+ node .isWord = true
34
+ return
35
+ }
36
+
37
+ index := ctoi (rune (s [0 ]))
38
+ child := node .childs [index ]
39
+ if child == nil {
40
+ child = newTrieNode ()
41
+ node .childs [index ] = child
42
+ }
43
+
44
+ child .isLeaf = false
45
+ child .insert (s [1 :])
46
+ }
47
+
48
+ func (node * trieNode ) autoComplete (s string ) []string {
49
+ next := node
50
+ for _ , r := range s {
51
+ next = next .childs [ctoi (r )]
52
+ if next == nil {
53
+ return nil
54
+ }
55
+ }
56
+
57
+ if next == nil {
58
+ return nil
59
+ }
60
+
61
+ return next .append (s )
62
+ }
63
+
64
+ func (node * trieNode ) append (s string ) []string {
65
+ var out []string
66
+ if node .isWord {
67
+ out = append (out , s )
68
+ }
69
+
70
+ for i , child := range node .childs {
71
+ if child == nil {
72
+ continue
73
+ }
74
+
75
+ prefix := s + string (itoc (rune (i )))
76
+
77
+ if child .isLeaf {
78
+ out = append (out , prefix )
79
+ continue
80
+ }
81
+
82
+ for _ , word := range child .append (prefix ) {
83
+ out = append (out , word )
84
+ }
85
+ }
86
+
87
+ return out
88
+ }
89
+
90
+ func itoc (i rune ) rune {
91
+ switch i {
92
+ case 26 :
93
+ return ' '
94
+ default :
95
+ return i + 'a'
96
+ }
97
+ }
98
+
99
+ func ctoi (c rune ) rune {
100
+ switch c {
101
+ case ' ' :
102
+ return 26
103
+ default :
104
+ return c - 'a'
105
+ }
106
+ }
Original file line number Diff line number Diff line change
1
+ package auto_complete_feature_test
2
+
3
+ import (
4
+ "testing"
5
+
6
+ sut "github.com/minizilla/minmax/geeksforgeeks/auto-complete-feature"
7
+ "github.com/minizilla/testr"
8
+ )
9
+
10
+ func TestAutoCompleteFeature (t * testing.T ) {
11
+ dict := []string {
12
+ "i am iron man" ,
13
+ "i am iron man endgame" ,
14
+ "i am iron man meme" ,
15
+ "i am venom" ,
16
+ "i am venom sound" ,
17
+ "i am venom morbius" ,
18
+ "i am batman" ,
19
+ }
20
+
21
+ tests := map [string ]struct {
22
+ q string
23
+ res []string
24
+ }{
25
+ "empty" : {"" , nil },
26
+ "can't complete" : {"i am man" , nil },
27
+ "incomplete" : {
28
+ "i am iro" ,
29
+ []string {
30
+ "i am iron man" ,
31
+ "i am iron man endgame" ,
32
+ "i am iron man meme" ,
33
+ },
34
+ },
35
+ "incomplete with space" : {
36
+ "i am venom " ,
37
+ []string {
38
+ "i am venom morbius" ,
39
+ "i am venom sound" ,
40
+ },
41
+ },
42
+ "complete" : {
43
+ "i am batman" ,
44
+ []string {
45
+ "i am batman" ,
46
+ },
47
+ },
48
+ }
49
+
50
+ for name , tc := range tests {
51
+ t .Run (name , func (t * testing.T ) {
52
+ assert := testr .New (t )
53
+ res := sut .Solution (tc .q , dict )
54
+ assert .Equal (res , tc .res )
55
+ })
56
+ }
57
+ }
You can’t perform that action at this time.
0 commit comments