请注意,下面的代码显示了控制台中的数组,而不是代码段输出
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?
答案 0 :(得分:0)
此解决方案使用属性isWord
对结束指示符进行了明显更改的对象结构,因为原始结构不反映'marc'
和'marcus'
等条目,因为如果仅'marc'
1}}是使用,树的末尾的零表示单词的结尾,但它不允许添加子字符串,因为该属性是基元而不是对象。
基本上这个解决方案首先创建一个包含单个字母的comlete树,然后连接所有只有一个子对象的属性。
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;
一种递归单遍方法,具有将单词插入树中以更新节点的功能。
它的工作原理是
使用对象的所有键检查给定的string
,如果string
以实际键开头,则使用部分字符串和trie的嵌套部分进行递归调用
否则,它会检查密钥和字符串中的字符数相同。
然后它检查计数器并创建一个带有公共部分和两个节点的新节点,旧节点内容和字符串的新节点。
由于新节点,旧节点不再需要并被删除,并且通过返回true
update
检查来停止迭代。
如果没有发生更新,则会分配一个字符串为键,值为零的新属性。
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;