Javascript: Find exactly 10 words in a prefix tree that start with a given prefix

倖福魔咒の 提交于 2019-12-01 23:04:52

Basically I take your model and apply a new method getWords(word[, count]) to the Trie class. I changed the method contains because I need the functionality in getWords as well. So I created a new method getNode, which returns the node where the word or part is found.

The method getWords first looks up the word (part) and then iterates through the data structure. When a word is found it is pushed to the result set. If the result set length is greater or equal to the required length, then the iteration (hence Array.prototype.some) is terminated and the recursive call of fork is stopped.

    that.getWords = function (word, count) {          function fork(n, w) {              function child(c) {                 return fork(n.children[c], w + c);             }              n.isWord && words.push(w);             return words.length >= count || Object.keys(n.children).some(child);         }          var words = [],             current_node = that.getNode(word);          if (current_node) {             fork(current_node, word);             return words;         }     } 

Side note: I changed this_is_the_end_of_a_word to isWord.

Input

  1. Create a new instance of Trie.
  2. Insert some words for testing.

Output

  1. Test if the trie contains 'motor', returns false.
  2. Test if the trie contains 'te', returns false.
  3. Test if the trie contains 'ten', returns true.
  4. Get all words that starts with 'ind' (8 available, shows 8).
  5. Get first 10 words that starts with 'in' (16 available, shows 10).
  6. The whole trie.

var Trie = function () {        var that = Object.create(Trie.prototype);      that.children = {}; //mapping: next character -> child nodes      that.isWord = false;        that.insertWord = function (word) {          var current_node = that;          for (var i = 0; i < word.length; i++) {              var c = word[i]              //if character is not in the trie already, add it              if (!(c in current_node.children)) {                  current_node.children[c] = Trie();              }              //update current_node              current_node = current_node.children[c];          };            //after adding all the chars of the word,          //you are at the end of a word          current_node.isWord = true;      }        that.insertWords = function (words) {          for (var i = 0; i < words.length; i++) {              that.insertWord(words[i]);          }      }        that.getNode = function (word) {          //start at the root          var current_node = that;          for (var i = 0; i < word.length; i++) {              var c = word[i];                //if the word's character isn't a child of the current_node,              //the word isn't in the trie              if (!(c in current_node.children)) {                  return;              }              //move down the trie, update current_node              current_node = current_node.children[c];          };          return current_node;      }        that.contains = function (word) {          var current_node = that.getNode(word);          if (current_node) {              return current_node.isWord;          }          return false;      }        that.getWords = function (word, count) {            function fork(n, w) {                function child(c) {                  return fork(n.children[c], w + c);              }                n.isWord && words.push(w);              return words.length >= count || Object.keys(n.children).some(child);          }            var words = [],              current_node = that.getNode(word);            if (current_node) {              fork(current_node, word);              return words;          }      }        // freeze does lock the isWord property, which is not required here      //Object.freeze(that);      return that;  }    var trie = new Trie();  trie.insertWords([      'car', 'cool', 'i', 'in', 'indeed', 'independence', 'india', 'indoor', 'induction',      'industrial', 'industry', 'indwell', 'inferior', 'informal', 'inhale', 'inn',      'inside', 'instance', 'intrepid', 'of', 'off', 'other', 'tea', 'ted', 'ten',      'to', 'zoo', 'zoom'  ]);  document.write(trie.contains('motor') + '<br>'); // false  document.write(trie.contains('te') + '<br>'); // false  document.write(trie.contains('ten') + '<br>'); // true  document.write('<pre>' + JSON.stringify(trie.getWords('ind'), 0, 4) + '</pre>');  document.write('<pre>' + JSON.stringify(trie.getWords('in', 10), 0, 4) + '</pre>');  document.write('<pre>' + JSON.stringify(trie, 0, 4) + '</pre>');
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!