Как построить Radix Tree в JavaScript?

Вдохновленный предсказанием следующего слова iOS7 iMessage, я решил попытаться написать скрипт, который на основе пользовательского ввода узнает, какие слова / буквы, скорее всего, хотят завершить текущее слово пользователя или какое слово, скорее всего, может быть желаемый следующий.

Для этого я собираюсь использовать структуру данных, очень похожую на Radix Tree (AKA a Patricia Trie).

Возьмем этот пользовательский ввод, например:

Я люблю мороженое

Исходя из этого, моя цель - создать следующую структуру данных:

var speakData = {
    "I": { //the key
        value: "I", //the stored value for this unit of the combination
        count: 1, //the number of times that this combination has occured
        followables: { // the next level of the tree; all combinations 
                       // that might follow this one
            " ": {
                value: " ",
                count: 1,
                followables: {
                    "l": {
                        value: "l",
                        count: 1,
                        followables: {
                            "i": {
                                value: "i",
                                count: 1,
                                followables: {
                                    "k": {
                                        value: "k",
                                        count: 1,
                                        followables: {
                                            "e": {
                                                value: "e",
                                                count: 1,
                                                followables: {
                                                    // and so on 
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

По сути, это Radix Tree с некоторой дополнительной информацией, позволяющей мне взвесить вероятность изученных возможностей, которые пользователь может захотеть набрать в следующий раз.

Из приведенного выше крайне ограниченного набора данных, когда пользователь вводит "I", наше лучшее (и единственное) предположение состоит в том, что следующим символом будет " ".

Итак, теперь, когда я объяснил свою цель и метод, вот мой вопрос:

Как я могу построить эту структуру данных из любого данного пользовательского ввода?

function learn(message, brain){
    for(var i = 0; i < message.length; i++){
        brain[message[i]] = {};
        brain[message[i]].value = message[i];
        brain[message[i]].count++;
        brain[message[i]].followables = 
    }
}

Это насколько я понял, но я не уверен, как рекурсивно вставить следующие значения в правильные позиции.

1 ответ

Просто создайте простую рекурсивную функцию, что-то вроде этого:

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)
  }
  return brain;
}

Конечно, вы также можете сделать это итеративным, а не рекурсивным.

// test code:
var brain = {};
brain = learn('test',brain);
brain = learn('testing',brain);
brain = learn('tes',brain);
brain = learn('yay',brain);
console.log(JSON.stringify(brain, null, 2));

Будет выводить что-то вроде этого:

{
  "t": {
    "value": "t",
    "count": 3,
    "followables": {
      "e": {
        "value": "e",
        "count": 3,
        "followables": {
          "s": {
            "value": "s",
            "count": 3,
            "followables": {
              "t": {
                "value": "t",
                "count": 2,
                "followables": {
                  "i": {
                    "value": "i",
                    "count": 1,
                    "followables": {
                      "n": {
                        "value": "n",
                        "count": 1,
                        "followables": {
                          "g": {
                            "value": "g",
                            "count": 1,
                            "followables": {}
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "y": {
    "value": "y",
    "count": 1,
    "followables": {
      "a": {
        "value": "a",
        "count": 1,
        "followables": {
          "y": {
            "value": "y",
            "count": 1,
            "followables": {}
          }
        }
      }
    }
  }
}
Другие вопросы по тегам