File tree 3 files changed +46
-0
lines changed
3 files changed +46
-0
lines changed Original file line number Diff line number Diff line change 1
1
import TrieNode from './TrieNode' ;
2
2
3
+ // Character that we will use for trie tree root.
3
4
const HEAD_CHARACTER = '*' ;
4
5
5
6
export default class Trie {
6
7
constructor ( ) {
7
8
this . head = new TrieNode ( HEAD_CHARACTER ) ;
8
9
}
9
10
11
+ /**
12
+ * @param {string } word
13
+ * @return {Trie }
14
+ */
10
15
addWord ( word ) {
11
16
const characters = Array . from ( word ) ;
12
17
let currentNode = this . head ;
18
+
13
19
for ( let charIndex = 0 ; charIndex < characters . length ; charIndex += 1 ) {
14
20
const isComplete = charIndex === characters . length - 1 ;
15
21
currentNode = currentNode . addChild ( characters [ charIndex ] , isComplete ) ;
16
22
}
23
+
24
+ return this ;
17
25
}
18
26
27
+ /**
28
+ * @param {string } word
29
+ * @return {string[] }
30
+ */
19
31
suggestNextCharacters ( word ) {
20
32
const lastCharacter = this . getLastCharacterNode ( word ) ;
21
33
@@ -26,17 +38,27 @@ export default class Trie {
26
38
return lastCharacter . suggestChildren ( ) ;
27
39
}
28
40
41
+ /**
42
+ * @param {string } word
43
+ * @return {boolean }
44
+ */
29
45
doesWordExist ( word ) {
30
46
return ! ! this . getLastCharacterNode ( word ) ;
31
47
}
32
48
49
+ /**
50
+ * @param {string } word
51
+ * @return {TrieNode }
52
+ */
33
53
getLastCharacterNode ( word ) {
34
54
const characters = Array . from ( word ) ;
35
55
let currentNode = this . head ;
56
+
36
57
for ( let charIndex = 0 ; charIndex < characters . length ; charIndex += 1 ) {
37
58
if ( ! currentNode . hasChild ( characters [ charIndex ] ) ) {
38
59
return null ;
39
60
}
61
+
40
62
currentNode = currentNode . getChild ( characters [ charIndex ] ) ;
41
63
}
42
64
Original file line number Diff line number Diff line change 1
1
import HashTable from '../hash-table/HashTable' ;
2
2
3
3
export default class TrieNode {
4
+ /**
5
+ * @param {string } character
6
+ * @param {boolean } isCompleteWord
7
+ */
4
8
constructor ( character , isCompleteWord = false ) {
5
9
this . character = character ;
6
10
this . isCompleteWord = isCompleteWord ;
7
11
this . children = new HashTable ( ) ;
8
12
}
9
13
14
+ /**
15
+ * @param {string } character
16
+ * @return {TrieNode }
17
+ */
10
18
getChild ( character ) {
11
19
return this . children . get ( character ) ;
12
20
}
13
21
22
+ /**
23
+ * @param {string } character
24
+ * @param {boolean } isCompleteWord
25
+ * @return {TrieNode }
26
+ */
14
27
addChild ( character , isCompleteWord = false ) {
15
28
if ( ! this . children . has ( character ) ) {
16
29
this . children . set ( character , new TrieNode ( character , isCompleteWord ) ) ;
@@ -19,14 +32,24 @@ export default class TrieNode {
19
32
return this . children . get ( character ) ;
20
33
}
21
34
35
+ /**
36
+ * @param {string } character
37
+ * @return {boolean }
38
+ */
22
39
hasChild ( character ) {
23
40
return this . children . has ( character ) ;
24
41
}
25
42
43
+ /**
44
+ * @return {string[] }
45
+ */
26
46
suggestChildren ( ) {
27
47
return [ ...this . children . getKeys ( ) ] ;
28
48
}
29
49
50
+ /**
51
+ * @return {string }
52
+ */
30
53
toString ( ) {
31
54
let childrenAsString = this . suggestChildren ( ) . toString ( ) ;
32
55
childrenAsString = childrenAsString ? `:${ childrenAsString } ` : '' ;
Original file line number Diff line number Diff line change @@ -25,6 +25,7 @@ describe('TrieNode', () => {
25
25
trieNode . addChild ( 'o' ) ;
26
26
27
27
expect ( trieNode . getChild ( 'a' ) . toString ( ) ) . toBe ( 'a' ) ;
28
+ expect ( trieNode . getChild ( 'a' ) . character ) . toBe ( 'a' ) ;
28
29
expect ( trieNode . getChild ( 'o' ) . toString ( ) ) . toBe ( 'o' ) ;
29
30
expect ( trieNode . getChild ( 'b' ) ) . toBeUndefined ( ) ;
30
31
} ) ;
You can’t perform that action at this time.
0 commit comments