在 JavaScript 中,我试图接受给定的用户输入并猜测 3 个最有可能完成用户当前(不完整)键入的单词的单词。猜测是基于用户过去的输入。我正在这里工作,在这个 JSFiddle 中。
我为记录用户过去的输入而构建的结构是修改后的基数树(AKA Patricia Trie):
输入:“ hey
”
{
"h": {
"value": "h",
"count": 1,
"followables": {
"e": {
"value": "e",
"count": 1,
"followables": {
"y": {
"value": "y",
"count": 1,
"followables": {}
}
}
}
}
}
}
这个数据结构构建得很完美,我认为它是实现所描述目标的最佳结构。我的问题是读取基数树数据以定义给定输入的 3 个最可能单词的功能。以上面的数据为例,如果用户输入“ h
”,猜测函数应该返回一个像这样的对象:
guess : {
1 : "hey",
2 : "",
3 : ""
}
所以这是我的代码/进度:
学习- 获取完整的输入字符串并将组合组织到基数树 ( brain
) 中:
function learn(message, brain) {
if (message.length == 0) return {}; // or do something else
var ch = message[0]; // get the first character
if (!brain[ch]) { // create new node when not exists
brain[ch] = {
value: ch,
count: 1,
followables: {}
};
} else { // increment count when exist
brain[ch].count += 1;
}
var substr = message.substring(1); // remove first character
if (substr) { // do it for the remaining substring
brain[ch].followables = learn(substr, brain[ch].followables);
} else {
renderData();
}
return brain;
}
这一切都做对了。不幸的是,下一个代码,用于读取数据并猜测用户输入的单词,并不好。我在处理对我来说非常复杂的功能时遇到了麻烦。我把它分成了几个小函数,因为我知道这是最好的做法,但我担心我弄得一团糟,可能会更简单:
猜测- 获取“学习的”字符串数据并猜测用户可能正在输入的单词 3:
function guess(progress, brain) {
console.log("Guessing based on: " + progress);
var guesses = {
0: "",
1: "",
2: ""
}
var firstChar = progress[0];
if (brain[firstChar]) {
var step = brain[firstChar];
for (var i = 0; i < progress.length; i++) {
var char = progress[i];
if (step.followables[char]) {
step = step.followables[char];
if (i == progress.length) {
var guesses = nextStrings(step.followables);
renderGuesses(guesses);
}
} else {
renderGuesses(guesses);
}
}
} else {
renderGuesses(guesses);
}
}
function renderGuesses(guesses) {
console.log(guesses);
$('#guess-1').text(guesses[0]);
$('#guess-2').text(guesses[1]);
$('#guess-3').text(guesses[2]);
}
function nextStrings(followables) {
console.log('Searching for next string...');
var results;
if (followables.length > 0) {
results = chooseRoutes(followables);
} else {
results = {
0: "",
1: "",
2: ""
}
}
console.log(result);
return result;
}
function chooseRoutes(followables) {
var results = {
0: {
value: "",
count: 0
},
1: {
value: "",
count: 0
},
2: {
value: "",
count: 0
}
};
for (var i = 0; i < followables.length; i++) {
var count = followables[i].count;
if (count > results[0].count) {
results[0].value = followStr(followables[i], "");
} else if (count > results[1].count) {
results[1].value = followStr(followables[i], "");
} else if (count > results[2].count) {
results[2].value = followStr(followables[i], "");
}
}
console.log(results);
return results;
}
function followStr(followables, str) {
var guess = {
value: "",
count: 0
};
for (var i = 0; i < followables.length; i++) {
if (followables[i].count > guess.count) {
guess = followables[i];
}
}
followables = guess.followables;
if (guess.value != " ") {
str += guess;
followStr(followables, str);
} else {
console.log(str);
return str;
}
}
旁注- 虽然在字典上进行模糊字符串搜索是一种更常见的方法,但学习方法是根据用户的写作/消息传递风格定制猜测并支持用户的非标准词汇(“ heyy
”,“ sup
” , " :P
", " lol
") - 这些猜测的结果可以与标准字典结果结合(并优先于)。