Skip to content

Removed usage of prefix in a node, just a key is enough #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 2, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 20 additions & 19 deletions Trie/Trie.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
// represents the leaf node's key from its parent, meaning thats the end of a word
const LEAF_NODE_NOTATION = "$"

class Node {
edges: Map<string, Node> = new Map()
prefix: string
isWordEnd: boolean = false

constructor(prefix = "") {
this.prefix = prefix
}

// adds the char to the edge if not present, and returns the edge
// or returns the edge if already present
addChar = (char: string): Node => {
if (this.edges.has(char)) {
return this.edges.get(char)!
}
const node = new Node(this.prefix + char)
const node = new Node()
this.edges.set(char, node)
return node
}

addLeaf = (): Node => {
const node = new Node(this.prefix)
this.edges.set(this.prefix, node)
const node = new Node()
this.edges.set(LEAF_NODE_NOTATION, node)
node.isWordEnd = true
return node
}
Expand Down Expand Up @@ -67,49 +65,52 @@ export default class Trie {
}

// walk the trie until we find the last matching char
_walkTrieForBestMatch = (word: string): { node: Node, length: number } => {
_walkTrieForBestMatch = (word: string): { node: Node, length: number, stringMatched: string } => {
let currentNode: Node = this._head
let stringMatched = ""
let i = 0;
for (;i < word.length; i++) {
const char = word.charAt(i)
const node = currentNode.getEdge(char)
if (node === undefined) break;
else {
stringMatched = stringMatched + char
currentNode = node
}
}
// the head node has a empty char, so the length will be equal to index that we have walked so far
return { node: currentNode, length: i }
return { node: currentNode, length: i, stringMatched }
}

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

hasWord = (word: string): boolean => {
const { node, length } = this._walkTrieForBestMatch(word)
const endNode = node.getEdge(word)
const endNode = node.getEdge(LEAF_NODE_NOTATION)
const hasEndNode = endNode !== undefined && endNode.isWordEnd
return (length === word.length && hasEndNode)
}

getSuggestions = (word: string, acceptPartialMatch = false): Set<string> => {
const { node } = this._walkTrieForBestMatch(word)
const { node, stringMatched } = this._walkTrieForBestMatch(word)
const patterns: Set<string> = new Set()
this._walkNodeToGetWords(node, patterns, acceptPartialMatch ? "" : word)
this._walkNodeToGetWords(node, patterns, acceptPartialMatch ? "" : word, stringMatched)
return patterns
}

Expand Down