From 80e3216609defba5c78763a803642d59be7378be Mon Sep 17 00:00:00 2001 From: Oleksii Trekhleb Date: Thu, 26 Jul 2018 18:02:34 +0300 Subject: [PATCH] Add annotations to Trie. --- src/data-structures/trie/Trie.js | 22 ++++++++++++++++++ src/data-structures/trie/TrieNode.js | 23 +++++++++++++++++++ .../trie/__test__/TrieNode.test.js | 1 + 3 files changed, 46 insertions(+) diff --git a/src/data-structures/trie/Trie.js b/src/data-structures/trie/Trie.js index 8174e1ca..8eff5a05 100644 --- a/src/data-structures/trie/Trie.js +++ b/src/data-structures/trie/Trie.js @@ -1,5 +1,6 @@ import TrieNode from './TrieNode'; +// Character that we will use for trie tree root. const HEAD_CHARACTER = '*'; export default class Trie { @@ -7,15 +8,26 @@ export default class Trie { this.head = new TrieNode(HEAD_CHARACTER); } + /** + * @param {string} word + * @return {Trie} + */ addWord(word) { const characters = Array.from(word); let currentNode = this.head; + for (let charIndex = 0; charIndex < characters.length; charIndex += 1) { const isComplete = charIndex === characters.length - 1; currentNode = currentNode.addChild(characters[charIndex], isComplete); } + + return this; } + /** + * @param {string} word + * @return {string[]} + */ suggestNextCharacters(word) { const lastCharacter = this.getLastCharacterNode(word); @@ -26,17 +38,27 @@ export default class Trie { return lastCharacter.suggestChildren(); } + /** + * @param {string} word + * @return {boolean} + */ doesWordExist(word) { return !!this.getLastCharacterNode(word); } + /** + * @param {string} word + * @return {TrieNode} + */ getLastCharacterNode(word) { const characters = Array.from(word); let currentNode = this.head; + for (let charIndex = 0; charIndex < characters.length; charIndex += 1) { if (!currentNode.hasChild(characters[charIndex])) { return null; } + currentNode = currentNode.getChild(characters[charIndex]); } diff --git a/src/data-structures/trie/TrieNode.js b/src/data-structures/trie/TrieNode.js index 36261702..cf89fdd6 100644 --- a/src/data-structures/trie/TrieNode.js +++ b/src/data-structures/trie/TrieNode.js @@ -1,16 +1,29 @@ import HashTable from '../hash-table/HashTable'; export default class TrieNode { + /** + * @param {string} character + * @param {boolean} isCompleteWord + */ constructor(character, isCompleteWord = false) { this.character = character; this.isCompleteWord = isCompleteWord; this.children = new HashTable(); } + /** + * @param {string} character + * @return {TrieNode} + */ getChild(character) { return this.children.get(character); } + /** + * @param {string} character + * @param {boolean} isCompleteWord + * @return {TrieNode} + */ addChild(character, isCompleteWord = false) { if (!this.children.has(character)) { this.children.set(character, new TrieNode(character, isCompleteWord)); @@ -19,14 +32,24 @@ export default class TrieNode { return this.children.get(character); } + /** + * @param {string} character + * @return {boolean} + */ hasChild(character) { return this.children.has(character); } + /** + * @return {string[]} + */ suggestChildren() { return [...this.children.getKeys()]; } + /** + * @return {string} + */ toString() { let childrenAsString = this.suggestChildren().toString(); childrenAsString = childrenAsString ? `:${childrenAsString}` : ''; diff --git a/src/data-structures/trie/__test__/TrieNode.test.js b/src/data-structures/trie/__test__/TrieNode.test.js index d4f92569..3edacd24 100644 --- a/src/data-structures/trie/__test__/TrieNode.test.js +++ b/src/data-structures/trie/__test__/TrieNode.test.js @@ -25,6 +25,7 @@ describe('TrieNode', () => { trieNode.addChild('o'); expect(trieNode.getChild('a').toString()).toBe('a'); + expect(trieNode.getChild('a').character).toBe('a'); expect(trieNode.getChild('o').toString()).toBe('o'); expect(trieNode.getChild('b')).toBeUndefined(); });