Skip to content

Commit 43c25eb

Browse files
committed
Removed usage of prefix in a node, just a key is enough
1 parent 5fa5dd7 commit 43c25eb

File tree

1 file changed

+20
-19
lines changed

1 file changed

+20
-19
lines changed

Trie/Trie.ts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
1+
// represents the leaf node's key from its parent, meaning thats the end of a word
2+
const LEAF_NODE_NOTATION = "$"
3+
14
class Node {
25
edges: Map<string, Node> = new Map()
3-
prefix: string
46
isWordEnd: boolean = false
57

6-
constructor(prefix = "") {
7-
this.prefix = prefix
8-
}
9-
108
// adds the char to the edge if not present, and returns the edge
119
// or returns the edge if already present
1210
addChar = (char: string): Node => {
1311
if (this.edges.has(char)) {
1412
return this.edges.get(char)!
1513
}
16-
const node = new Node(this.prefix + char)
14+
const node = new Node()
1715
this.edges.set(char, node)
1816
return node
1917
}
2018

2119
addLeaf = (): Node => {
22-
const node = new Node(this.prefix)
23-
this.edges.set(this.prefix, node)
20+
const node = new Node()
21+
this.edges.set(LEAF_NODE_NOTATION, node)
2422
node.isWordEnd = true
2523
return node
2624
}
@@ -67,49 +65,52 @@ export default class Trie {
6765
}
6866

6967
// walk the trie until we find the last matching char
70-
_walkTrieForBestMatch = (word: string): { node: Node, length: number } => {
68+
_walkTrieForBestMatch = (word: string): { node: Node, length: number, stringMatched: string } => {
7169
let currentNode: Node = this._head
70+
let stringMatched = ""
7271
let i = 0;
7372
for (;i < word.length; i++) {
7473
const char = word.charAt(i)
7574
const node = currentNode.getEdge(char)
7675
if (node === undefined) break;
7776
else {
77+
stringMatched = stringMatched + char
7878
currentNode = node
7979
}
8080
}
8181
// the head node has a empty char, so the length will be equal to index that we have walked so far
82-
return { node: currentNode, length: i }
82+
return { node: currentNode, length: i, stringMatched }
8383
}
8484

85-
// send empty word to accept partial matches
86-
_walkNodeToGetWords = (node: Node, patterns: Set<string>, word = "") => {
85+
// send empty word to accept partial matches, parent is used for recursion
86+
_walkNodeToGetWords = (node: Node, patterns: Set<string>, word = "", parent = "") => {
8787
if (node.isWordEnd) {
8888
// the if check is to avoid partial matches
89-
// for example, when we check for "partyy" we should not return "part"
90-
if (word.length <= node.prefix.length) {
91-
patterns.add(node.prefix)
89+
// for example, when we check for "partyy" we should not return "part" or "party"
90+
if (word.length <= parent.length) {
91+
patterns.add(parent)
9292
}
9393
return
9494
}
9595
for (const [key, value] of node.edges) {
9696
// the next constructed words' predecessor must have have the last predecssor + current key
9797
// like "lo" + "r" then onto "lor" then "e" and "m"
98-
this._walkNodeToGetWords(value, patterns, word)
98+
const nextParent = key === LEAF_NODE_NOTATION ? parent : (parent + key) // when key is "$", dont add it to parent string
99+
this._walkNodeToGetWords(value, patterns, word, nextParent)
99100
}
100101
}
101102

102103
hasWord = (word: string): boolean => {
103104
const { node, length } = this._walkTrieForBestMatch(word)
104-
const endNode = node.getEdge(word)
105+
const endNode = node.getEdge(LEAF_NODE_NOTATION)
105106
const hasEndNode = endNode !== undefined && endNode.isWordEnd
106107
return (length === word.length && hasEndNode)
107108
}
108109

109110
getSuggestions = (word: string, acceptPartialMatch = false): Set<string> => {
110-
const { node } = this._walkTrieForBestMatch(word)
111+
const { node, stringMatched } = this._walkTrieForBestMatch(word)
111112
const patterns: Set<string> = new Set()
112-
this._walkNodeToGetWords(node, patterns, acceptPartialMatch ? "" : word)
113+
this._walkNodeToGetWords(node, patterns, acceptPartialMatch ? "" : word, stringMatched)
113114
return patterns
114115
}
115116

0 commit comments

Comments
 (0)