Структура данных по типу словаря T9
Как работает словарь T9? Какова структура данных позади нее. Если мы наберем "4663", мы получим "хороший", когда мы нажимаем кнопку "мы", затем "домой" и т.д.
EDIT: если пользователь набирает 46, тогда он должен показывать "go", а при нажатии стрелка должна показывать "нет" и т.д.
Ответы
Ответ 1
Он может быть реализован несколькими способами, один из которых Trie. Маршрут представлен цифрами, а узлы указывают на сбор слов.
Он может быть реализован с использованием вложенных хеш-таблиц, ключ хеш-таблицы - это буква и на каждой цифре алгоритм вычисляет все возможные маршруты (маршруты O (3 ^ n)).
Ответ 2
4663
переводится на
{G, Н, I} {М, N, О} {М, N, О} {D, Е, F}
T9 работает, фильтруя возможности вниз последовательно, начиная с первых возможных букв. Итак, первым шагом в вашем примере будет фильтрация списка слов со всеми словами, начинающимися с G, H или I. Следующий шаг, возьмите этот список и отфильтруйте второй буквой M, N, O. И так далее...
Ответ 3
Я думаю, что T9 использует Trie на основе бит-карты. На первом уровне есть 32-битное (я предполагаю, что они были расширены до 32), где каждый бит представляет букву. Все буквы, которые являются действительными в качестве начальных букв для слова, имеют свой бит.
На следующем уровне есть одна 32-битная карта для каждого из этих битов, которые были установлены на предыдущем уровне. На этих картах каждый бит устанавливается, если соответствующая буква действительна как вторая буква в слове, причем начальная буква определяется первым уровнем.
Затем структура продолжается. Использование однобитовой для письма делает очень эффективное хранилище. Однако схема адресации должна быть сложной. Также может быть какая-то оптимизация, использующая приведенную выше схему для коротких слов при использовании чего-то еще для более длинных слов.
Ответ 4
Я предполагаю, что до тех пор, пока T9 не использует trie, где ссылки представлены растровым изображением (1 бит на букву). Это называется сжатой структурой данных, как объясняет Стив Ханов:
http://stevehanov.ca/blog/index.php?id=120
Ответ 5
Я бы, вероятно, сделал это, начав со словаря, затем (для каждого слова) подталкивает слово в список, на который вводят цифры, которые могут образовывать слово.
Затем вам, вероятно, придется сортировать результирующие списки в некотором роде, поэтому более вероятные слова появляются перед менее вероятными словами (если у вас есть пространство, я бы также включил небольшую область для счетчика, поэтому мы можем пошаговое повторное сортирование этих ИЛИ просто mov ethe, используемых последним в списке предложений, поэтому мы со временем стремимся дать пользователю лучший ответ).
Таким образом, когда у вас есть 4663 в качестве входа, вы можете довольно просто получить соответствующий связанный список wit ha примерно O (1) поиск хеш-таблицы.
Ответ 6
Реализация С# с использованием Trie
public interface ICellT9
{
void Add(string a_name);
List<string> GetNames(string a_number);
}
public class Cell : ICellT9
{
private Dictionary<int, Cell> m_nodeHolder;
private List<string> m_nameList;
public Cell()
{
m_nameList = new List<string>();
m_nodeHolder = new Dictionary<int, Cell>();
for (int i = 2; i < 10; i++)
{
m_nodeHolder.Add(i, null);
}
}
public void Add(string a_name)
{
Add(a_name, a_name);
}
private void Add(string a_name, string a_originalName)
{
if (string.IsNullOrEmpty(a_name) &&
(string.IsNullOrEmpty(a_originalName) == false))
{
m_nameList.Add(a_originalName);
}
else
{
int l_firstNumber = CharToNumber(a_name[0].ToString());
if (m_nodeHolder[l_firstNumber] == null)
{
m_nodeHolder[l_firstNumber] = new Cell();
}
m_nodeHolder[l_firstNumber].Add(a_name.Remove(0, 1), a_originalName);
}
}
public List<string> GetNames(string a_number)
{
List<string> l_result = null;
if (string.IsNullOrEmpty(a_number))
{
return l_result;
}
int l_firstNumber = a_number[0] - '0';
if (a_number.Length == 1)
{
l_result = m_nodeHolder[l_firstNumber].m_nameList;
}
else if(m_nodeHolder[l_firstNumber] != null)
{
l_result = m_nodeHolder[l_firstNumber].GetNames(a_number.Remove(0, 1));
}
return l_result;
}
private int CharToNumber(string c)
{
int l_result = 0;
if (c == "a" || c == "b" || c == "c")
{
l_result = 2;
}
else if (c == "d" || c == "e" || c == "f")
{
l_result = 3;
}
else if (c == "g" || c == "h" || c == "i")
{
l_result = 4;
}
else if (c == "j" || c == "k" || c == "l")
{
l_result = 5;
}
else if (c == "m" || c == "n" || c == "o")
{
l_result = 6;
}
else if (c == "p" || c == "q" || c == "r" || c == "s")
{
l_result = 7;
}
else if (c == "t" || c == "u" || c == "v")
{
l_result = 8;
}
else if (c == "w" || c == "x" || c == "y" || c == "z")
{
l_result = 9;
}
return l_result;
}
}