В JavaScript я пытаюсь принять данный пользовательский ввод и угадать 3 наиболее вероятных слова, которые могут завершить текущее (неполное) введенное пользователем слово. Предположение основано на прошлых входных данных пользователя. Я работаю над этим здесь, в этом JSFiddle.
Структура, которую я создаю для записи прошлых входных данных пользователя, представляет собой модифицированное дерево оснований (также известное как Патрисия Три):
Ввод: "hey
"
{
"h": {
"value": "h",
"count": 1,
"followables": {
"e": {
"value": "e",
"count": 1,
"followables": {
"y": {
"value": "y",
"count": 1,
"followables": {}
}
}
}
}
}
}
Эта структура данных построена идеально, и я думаю, что это лучшая структура для достижения описанной цели. Моя проблема заключается в функции для чтения данных Radix Tree, чтобы определить 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
") - результаты этих догадок можно комбинировать (и иметь приоритет над) стандартными результатами словаря.
guess
. Является ли функция/общая цель сложной/продвинутой, или мне просто нужно больше практики? Я изучал JS в течение последних 2-3 лет старшей школы, и мне любопытно узнать, смогу ли я на данный момент пройти через что-то подобное... - person   schedule 16.02.2015.count
? - person Bergi   schedule 19.02.2015count
представляет количество раз, когда комбинация была записана, таким образом записывая вероятность. - person   schedule 19.02.20151x h, 1x he, 1x hey
- person Bergi   schedule 19.02.2015h
, мы можем сразу же проследить по дереву, чтобы узнать, что его вторая буква, скорее всего,e
, не спускаясь по всей ветке и не проверяя всеh
слова, чтобы наконец выяснить, что строкаhello
скорее всего. - person   schedule 19.02.2015h
, из 100 различных комбинаций, которые могут следовать за ним, мы можем сразу знать, что нужно следовать ветвямe
a
o
только для наших 3 предположений, потому что эти вероятности хранятся на каждом уровне. - person   schedule 19.02.2015