[removed] Find exactly 10 words in a prefix tree that start with a given prefix

前端 未结 1 1300
醉话见心
醉话见心 2021-01-20 10:31

I have a trie (also called a prefix tree). Given a prefix, I want to get a list of ten words that start with the prefix.

相关标签:
1条回答
  • 2021-01-20 10:41

    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>');

    0 讨论(0)
提交回复
热议问题