从这个js代码制作后缀的简单方法是什么?

时间:2018-02-03 16:49:55

标签: javascript trie patricia-trie

请注意,下面的代码显示了控制台中的数组,而不是代码段输出

var nodes = ["maria", "mary", "marks", "michael"];

function insert_word(split_nodes) {
  var rest = [];
  for (var i = 0; i < split_nodes.length; i++) {
    //console.log(current);
    var word = split_nodes[i];
    var letters = word.split("");
    var current = rest;
    console.log(current);
    for (var j = 0; j < letters.length; j++) {
      var character = letters[j];
      var position = current[character];
      if (position == null) {
        current = current[character] = j == letters.length - 1 ? 0 : {};
      } else {
        current = current[character];
      }
    }
  }
}
insert_word(nodes);

以上输出

M :{a : {r :{i :{a :0},
    k :0,   
    y :
    },
},
    i :{c :{h :{a :{e :{l :0}}}}}}}

但我想输出这个:

M :{ar:{ia:0,
    k :0,   
    y :0
    },
 ichael :0
}

任何人都可以帮我从我的代码中找出这个输出吗?我怎么能用这段代码制作suffeix?

1 个答案:

答案 0 :(得分:0)

此解决方案使用属性isWord对结束指示符进行了明显更改的对象结构,因为原始结构不反映'marc''marcus'等条目,因为如果仅'marc' 1}}是使用,树的末尾的零表示单词的结尾,但它不允许添加子字符串,因为该属性是基元而不是对象。

基本上这个解决方案首先创建一个包含单个字母的comlete树,然后连接所有只有一个子对象的属性。

&#13;
&#13;
function join(tree) {
    Object.keys(tree).forEach(key => {
        var object = tree[key],
            subKeys = Object.keys(object),
            joinedKey = key,
            found = false;    

        if (key === 'isWord') {
            return;
        }
        while (subKeys.length === 1 && subKeys[0] !== 'isWord') {
            joinedKey += subKeys[0];
            object = object[subKeys[0]];
            subKeys = Object.keys(object);
            found = true;
        }
        if (found) {
            delete tree[key];
            tree[joinedKey] = object;
        }
        join(tree[joinedKey]);
    });
}

var node = ["maria", "mary", "marks", "michael"],
    tree = {};

node.forEach(string => [...string].reduce((t, c) => t[c] = t[c] || {}, tree).isWord = true);
console.log(tree);

join(tree);
console.log(tree);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

一种递归单遍方法,具有将单词插入树中以更新节点的功能。

它的工作原理是

  • 使用对象的所有键检查给定的string,如果string以实际键开头,则使用部分字符串和trie的嵌套部分进行递归调用

  • 否则,它会检查密钥和字符串中的字符数相同。

    然后它检查计数器并创建一个带有公共部分和两个节点的新节点,旧节点内容和字符串的新节点。

    由于新节点,旧节点不再需要并被删除,并且通过返回true update检查来停止迭代。

  • 如果没有发生更新,则会分配一个字符串为键,值为零的新属性。

&#13;
&#13;
function insertWord(tree, string) {
    var keys = Object.keys(tree),
        updated = keys.some(function (k) {
            var i = 0;

            if (string.startsWith(k)) {
                insertWord(tree[k], string.slice(k.length));
                return true;
            }
            while (k[i] === string[i] && i < k.length) {
                i++;
            }
            if (i) {
                tree[k.slice(0, i)] = { [k.slice(i)]: tree[k], [string.slice(i)]: 0 };
                delete tree[k];
                return true;
            }
        });

    if (!updated) {            
        tree[string] = 0;
    }
}

var words = ["maria", "mary", "marks", "michael"],
    tree = {};

words.forEach(insertWord.bind(null, tree));
console.log(tree);

insertWord(tree, 'mara');
console.log(tree);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;