Trie 实现中出现错误(Javascript)

问题描述 投票:0回答:2

我正在实现 Trie 算法的 add 函数,但它给了我以下错误:

未捕获类型错误:节点不是构造函数

...在此代码行中:

node.children[char_pos]=new Array(string[0], new node());

请问,你能告诉我发生了什么事吗?

我感谢任何帮助。

这是我的代码:

var node = function(){

    this.children= new Array(26);
    this.last_char=false;
};

function add(word, node){

    char_pos=word.charCodeAt(0) - 'a'.charCodeAt(0);

    if(word.length==1){

        if(node.children[char_pos]==null){ 

            node.children[char_pos]=word[0];
            node.last_char=true;
            return;

        }else{
            return;
        };

    }else{

        if(node.children[char_pos]==null){ 
            node.children[char_pos]=new Array(word[0], new node());
        };
    };

    word=word.substring(1);
    add(word, node.children[char_pos][1]);
};
javascript tree trie
2个回答
1
投票

首先你声明

var node // = ...

然后

function add(word, node){

我想你会用节点的一些实例来调用,一个节点,而不是你的节点构造函数

在您的函数 add 中,identifier node 解析为您的参数“node”,具有 相同标识符 的构造函数在此处不可用。 你会写

node = new node()
你会失去节点功能吗?

标准通过使用第一个大写字母命名构造函数或类(如 Node)以及 Node 的实例、node 来帮助您解决此问题,这样您就不会覆盖标识符。

事实上,您确实应该选择尚未使用的标识符,因为您将覆盖它们,并使后者不可用。


0
投票
// we start with the TrieNode
const TrieNode = function (key) {
  // the "key" value will be the character in sequence
  this.key = key;
  
  // we keep a reference to parent
  this.parent = null;
  
  // we have hash of children
  this.children = {};
  
  // check to see if the node is at the end
  this.end = false;
  
  this.getWord = function() {
    let output = [];
    let node = this;

    while (node !== null) {
      output.unshift(node.key);
      node = node.parent;
    }

    return output.join('');
  };
}

const Trie = function() {
  this.root = new TrieNode(null);
  
  // inserts a word into the trie.
  this.insert = function(word) {
    let node = this.root; // we start at the root

    // for every character in the word
    for(let i = 0; i < word.length; i++) {
      // check to see if character node exists in children.
      if (!node.children[word[i]]) {
        // if it doesn't exist, we then create it.
        node.children[word[i]] = new TrieNode(word[i]);

        // we also assign the parent to the child node.
        node.children[word[i]].parent = node;
      }

      // proceed to the next depth in the trie.
      node = node.children[word[i]];

      // finally, we check to see if it's the last word.
      if (i == word.length-1) {
        // if it is, we set the end flag to true.
        node.end = true;
      }
    }
  };
  
  // check if it contains a whole word.
  this.search = function(word) {
    let node = this.root;

    // for every character in the word
    for(let i = 0; i < word.length; i++) {
      // check to see if character node exists in children.
      if (node.children[word[i]]) {
        // if it exists, proceed to the next depth of the trie.
        node = node.children[word[i]];
      } else {
        // doesn't exist, return false since it's not a valid word.
        return false;
      }
    }

    // we finished going through all the words, but is it a whole word?
    return node.end;
  };
  
  // returns every word with given prefix
  this.startsWith = function(prefix) {
    let node = this.root;
    let output = [];

    // for every character in the prefix
    for(let i = 0; i < prefix.length; i++) {
      // make sure prefix actually has words
      if (node.children[prefix[i]]) {
        node = node.children[prefix[i]];
      } else {
        // there's none. just return it.
        return output;
      }
    }

    // recursively find all words in the node
    findAllWords(node, output);

    return output;
  };
  
  // recursive function to find all words in the given node.
  const findAllWords = (node, arr) => {
    // base case, if node is at a word, push to output
    if (node.end) {
      arr.unshift(node.getWord());
    }

    // iterate through each children, call recursive findAllWords
    for (let child in node.children) {
      findAllWords(node.children[child], arr);
    }
  }

  // removes a word from the trie.
  this.remove = function (word) {
      let root = this.root;

      if(!word) return;

      // recursively finds and removes a word
      const removeWord = (node, word) => {

          // check if current node contains the word
          if (node.end && node.getWord() === word) {

              // check and see if node has children
              let hasChildren = Object.keys(node.children).length > 0;

              // if has children we only want to un-flag the end node that marks the end of a word.
              // this way we do not remove words that contain/include supplied word
              if (hasChildren) {
                  node.end = false;
              } else {
                  // remove word by getting parent and setting children to empty dictionary
                  node.parent.children = {};
              }

              return true;
          }

          // recursively remove word from all children
          for (let key in node.children) {
              removeWord(node.children[key], word)
          }

          return false
      };

      // call remove word on root node
      removeWord(root, word);
  };
}

干净的 JavaScript trie 实现。

© www.soinside.com 2019 - 2024. All rights reserved.