【问题标题】:How to retrieve all the data/words in a radix trie in Javascript如何在 Javascript 中检索 radix trie 中的所有数据/单词
【发布时间】:2015-12-12 05:54:38
【问题描述】:

我已经能够在 JavaScript 中编写一个 Radix 树示例(未优化,所以不要判断)

到目前为止,我已经能够AddTransverseFind 节点。

我在编写一个可以retrieve所有节点的函数时遇到问题,这是我需要帮助的地方。提前谢谢你

// As illustrated in:
// http://programminggeeks.com/c-code-for-radix-tree-or-trie/

// Make a class of the Tree so that you can define methods all nodes of the tree
// which are actually Trees in structure inherit the functions
function Tree() {
    this.character = undefined;

    // if this node is the end of a complete word
    // this was we can differentiate "sell" and "sells" if both are searched for
    this.isword = false;

    // How to nest the nodes, thus creating a tree structure
    this.node = {}; // [new Tree(), new Tree(), new Tree()];

    // abcdefghijklmnopqrstuvwxyz
    var start = 97,
        end = start + 25;

    function constructor(that) {
        for (var x = start; x <= end; x++) {
            // for now they are all unsigned objects
            that.node[x] = null // new Tree()
        }
        return that;
    }

    constructor(this);
    return this;
}

Tree.prototype.addNode = function(word) {
    return this.transverseNodes(word, true);
};

Tree.prototype.searchForNodes = function(word) {
    return this.transverseNodes(word, false);
};

Tree.prototype.stringToNodes = function(word) {
    var nodeArray = []
    for (var x = 0, length = word.length; x < length; x++) {
        nodeArray.push(word.charCodeAt(x));
    }
    return nodeArray;
};

Tree.prototype.transverseNodes = function(word, bool) {
    // make all of the letters lowercase to create uniformity
    var nodes = this.stringToNodes(word.toLowerCase());
    // console.log(nodes);

    // start with parent/root tree
    var currentTreeNode = this

    // transverse checking if node has been added, if not add it
    // if it was already added and it terminates a word set it "isword" property to true
    for (var i = 0, length = nodes.length; i < length; i++) {
        var node = nodes[i];

        // If the current tree node is defined so not overwrite it
        if (currentTreeNode.node[node] === null) {

            if (!bool) {
                // if bool is undefined of false, then this is a search
                return false;
            }

            // create a node
            currentTreeNode.node[node] = new Tree();
            currentTreeNode.node[node].character = String.fromCharCode(node);
        }

        // check if the node is the last character of the word
        if ((nodes.length - 1) === i) {
            // console.log(nodes.length - 1, i)
            if (!bool) {
                // if bool is undefined of false, then this is a search
                return true;
            }

            currentTreeNode.node[node].isword = true;
        }

        // get into the nested node
        currentTreeNode = currentTreeNode.node[node];
    };

    return this;
};

var tree = new Tree()

// Create the nodes
tree.addNode("cat");
tree.addNode("camel");
tree.addNode("condom");
tree.addNode("catastrophe");
tree.addNode("grandma");
tree.addNode("lamboghini");

// Search the nodes
console.log(tree.searchForNodes("cat")); // true
console.log(tree.searchForNodes("catapult")); // false
console.log(tree.searchForNodes("catastrophe")); // true
console.log(tree.searchForNodes("mama")); // false
console.log(tree.searchForNodes("lamboghini")); // true

// retrieving all node
// console.log(tree.retrieveAllNodes());

【问题讨论】:

    标签: javascript algorithm radix-tree


    【解决方案1】:

    我不确定你是否这样做是为了学习,但如果不是,我建议你不要重新发明轮子,并尝试一些为此目的已经存在的库,例如Javid Jamae's RadixTreeJS.

    【讨论】:

      【解决方案2】:

      此提案采用迭代和递归方法来获取树中的单词。

      'use strict';
      // As illustrated in:
      // http://programminggeeks.com/c-code-for-radix-tree-or-trie/
      
      // Make a class of the Tree so that you can define methods all nodes of the tree
      // which are actually Trees in structure inherit the functions
      function Tree() {
          this.character = undefined;
      
          // if this node is the end of a complete word
          // this was we can differentiate "sell" and "sells" if both are searched for
          this.isword = false;
      
          // How to nest the nodes, thus creating a tree structure
          this.node = {}; // [new Tree(), new Tree(), new Tree()];
      
          // abcdefghijklmnopqrstuvwxyz
          var start = 97,
              end = start + 25;
      
          function constructor(that) {
              for (var x = start; x <= end; x++) {
                  // for now they are all unsigned objects
                  that.node[x] = null // new Tree()
              }
              return that;
          }
      
          constructor(this);
          return this;
      }
      
      Tree.prototype.addNode = function (word) {
          return this.transverseNodes(word, true);
      };
      
      Tree.prototype.searchForNodes = function (word) {
          return this.transverseNodes(word, false);
      };
      
      Tree.prototype.stringToNodes = function (word) {
          var nodeArray = []
          for (var x = 0, length = word.length; x < length; x++) {
              nodeArray.push(word.charCodeAt(x));
          }
          return nodeArray;
      };
      
      Tree.prototype.transverseNodes = function (word, bool) {
          // make all of the letters lowercase to create uniformity
          var nodes = this.stringToNodes(word.toLowerCase());
          // console.log(nodes);
      
          // start with parent/root tree
          var currentTreeNode = this
      
          // transverse checking if node has been added, if not add it
          // if it was already added and it terminates a word set it "isword" property to true
          for (var i = 0, length = nodes.length; i < length; i++) {
              var node = nodes[i];
      
              // If the current tree node is defined so not overwrite it
              if (currentTreeNode.node[node] === null) {
      
                  if (!bool) {
                      // if bool is undefined of false, then this is a search
                      return false;
                  }
      
                  // create a node
                  currentTreeNode.node[node] = new Tree();
                  currentTreeNode.node[node].character = String.fromCharCode(node);
              }
      
              // check if the node is the last character of the word
              if ((nodes.length - 1) === i) {
                  // console.log(nodes.length - 1, i)
                  if (!bool) {
                      // if bool is undefined of false, then this is a search
                      return true;
                  }
                  currentTreeNode.node[node].isword = true;
              }
      
              // get into the nested node
              currentTreeNode = currentTreeNode.node[node];
          };
      
          return this;
      };
      
      Tree.prototype.retrieveAllNodes = function () {
      
          // function for traversing over object, takes the object and an empty string for
          // the appearing words, acts as closure for the object
          function iterObject(o, r) {
              // how i like to start functions with return (...)
              // returns basically the up coming word.
              // reason for reduce, this provides a return value, with the letters
              // of the path
              return Object.keys(o).reduce(function (r, key) {
                  // check if the key property has a truthy value (remember the default
                  // null values)
                  if (o[key]) {
                      // if so, check the property isword
                      if (o[key].isword) {
                          // if its truty here, we have a hit, a word is found
                          wordList.push(r + o[key].character);
                      };
                      // check for children
                      if (o[key].node) {
                          // if node exist, go on with a new iteration and a new word
                          // extension
                          iterObject(o[key].node, r + o[key].character);
                      }
                  }
                  // return the inevitable word stem
                  return r;
              }, r);
          }
      
          var wordList = [];
          iterObject(this.node, '');
          return wordList;
      }
      
      var tree = new Tree();
      
      // Create the nodes
      tree.addNode("cat");
      tree.addNode("camel");
      tree.addNode("condom");
      tree.addNode("catastrophe");
      tree.addNode("grandma");
      tree.addNode("lamboghini");
      
      // Search the nodes
      console.log(tree.searchForNodes("cat"));         // true
      console.log(tree.searchForNodes("catapult"));    // false
      console.log(tree.searchForNodes("catastrophe")); // true
      console.log(tree.searchForNodes("mama"));        // false
      console.log(tree.searchForNodes("lamboghini"));  // true
      
      // retrieving all words
      console.log(JSON.stringify(tree.retrieveAllNodes(), 0, 4));
      // retrieving whole tree
      console.log(JSON.stringify(tree, 0, 4));
      .as-console-wrapper { max-height: 100% !important; top: 0; }

      奖励:下面是一个开销很小的版本。

      'use strict';
      function Tree() {
          return this;
      }
      
      Tree.prototype.addNode = function (word) {
          this.stringToNodes(word).reduce(function (node, character, i, a) {
              if (!node[character]) {
                  node[character] = {};
              }
              if (i === a.length - 1) {
                  node[character].isword = true;
              }
              return node[character];
          }, this);
          return this;
      };
      
      Tree.prototype.searchForNodes = function (word) {
      
          function iterObject(o, r) {
              return Object.keys(o).reduce(function (r, key) {
                  if (key === 'isword' && r === word) {
                      found = true;
                  }
                  typeof o[key] === 'object' && iterObject(o[key], r + key);
                  return r;
              }, r);
          }
      
          var found = false;
          iterObject(this, '');
          return found;
      };
      
      
      Tree.prototype.stringToNodes = function (word) {
          return word.toLowerCase().split('');
      };
      
      Tree.prototype.retrieveAllNodes = function () {
      
          function iterObject(o, r) {
              return Object.keys(o).reduce(function (r, key) {
                  key === 'isword' && wordList.push(r);
                  typeof o[key] === 'object' && iterObject(o[key], r + key);
                  return r;
              }, r);
          }
      
          var wordList = [];
          iterObject(this, '');
          return wordList;
      }
      
      var tree = new Tree();
      
      // Create the nodes
      tree.addNode("cat");
      tree.addNode("camel");
      tree.addNode("condom");
      tree.addNode("catastrophe");
      tree.addNode("grandma");
      tree.addNode("lamboghini");
      
      // Search the nodes
      console.log(tree.searchForNodes("cat"));         // true
      console.log(tree.searchForNodes("catapult"));    // false
      console.log(tree.searchForNodes("catastrophe")); // true
      console.log(tree.searchForNodes("mama"));        // false
      console.log(tree.searchForNodes("lamboghini"));  // true
      
      // retrieving all words
      console.log(JSON.stringify(tree.retrieveAllNodes(), 0, 4));
      // retrieving whole tree
      console.log(JSON.stringify(tree, 0, 4));
      .as-console-wrapper { max-height: 100% !important; top: 0; }

      【讨论】:

      • 非常感谢。那是一些糟糕的代码。从来没有理解什么是 map reduce,这是今天的新事物。 :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-20
      • 2022-11-25
      • 1970-01-01
      • 2019-08-05
      • 2013-06-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多