Использование бинарного дерева поиска как проверка орфографии

голоса
4

Удивление самый сверхвысоком способ сделать дерево двоичного поиска в проверки орфографии, читая, скажем 1000 слов файл словаря, а затем с его проверить другой документ, который имеет сказать пару абзацев.

Задан 05/12/2008 в 03:05
источник пользователем
На других языках...                            


8 ответов

голоса
8

тройная дерево Trie будет более эффективным

Ответил 05/12/2008 в 03:22
источник пользователем

голоса
0

Если вам нужно сделать автоматический предложить поиск / префиксов, а также, то Патрисия дерево или радикс дерево стоит посмотреть.

Ответил 05/12/2008 в 03:26
источник пользователем

голоса
0

В примере, который вы дали, производительность, скорее всего, не имеет значения, так как на ПК, вся операция занимает примерно 1% от времени, которое требуется пользователю прочитать первый результат вы показываете, если вы не используете полностью глупое алгоритм , Но все же, я буду считать, что проблема является достаточно большим, что производительность является проблемой.

Если файл словаря отсортированы (как большинство), и если текст небольшой по отношению к словарю, как вы описываете, то я бы очень хотелось, чтобы отсортировать текст, возможно, удаление дубликатов, а затем перебирать в обоих списках бок -side используя ту же процедуру, как сортировки слияния, за исключением того, сообщает ли каждый текст слово в словаре, вместо вывода списка слитого.

Это делает работу в о М журнала M сравнений для сортировки, а также в большинстве сравнений N + M для итерации, (возможно меньше, но не сложность меньше). Это довольно близко к оптимальной сложности для работы единовременной: чтобы избавиться от линейного члена в N вы должны найти способы, чтобы не прочитать весь словарь с диска на всех. Я уверен, что это можно bsearch в файл, особенно с учетом того, что слова довольно короткие, но для малых N это только догадываться ли ищешь о месте на самом деле будет быстрее, чем последовательно доступ к данным.

Он имеет следующие характеристики:

  • Вам не нужно держать в памяти словаря, только текст.
  • Тем не менее, вы делаете только один проход над файлом словарь.
  • Вы не делать какую-либо дорогостоящую обработку словаря.

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

Если словарь действительно огромный, то вы могли бы извлечь выгоду от хранения его на диске в предварительно обработанном виде эквивалентного несбалансированного дерева, взвешенном в соответствии с относительными частотами различных слов в языке. Тогда вы можете сделать меньше, чем O (N) доступ к диску для небольших текстов, а также на большинстве операционных систем не беспокоить загружая его в память вообще, просто MMAP файл и пусть ОС беспокоиться об этом. Для большого словаря, целые кластеры, содержащие слова, начинающиеся с «диметиловый» не прикасались.

Еще одно соображением является скошенным деревом для словаря. Расставленное дерево дисбалансов себя, как вы смотрите вещи в нем, для того, чтобы часто используемых значениях быстрее найти. Большинство текстов использует небольшое количество слов, несколько раз, так что если текст достаточно долго, чтобы оправдать издержки этого выиграет в конце концов.

Оба выше подвержены точкам Steven A Lowe, что для строк, Trie бьется нормальное дерево. Не знаю, будете ли вы найти вне-полки расставленного синтаксическое дерево, хотя.

Ответил 05/12/2008 в 03:55
источник пользователем

голоса
1

Если вы просто пытаетесь увидеть, если конкретное слово существует в словаре (то есть, это правильно пишется), то я не думаю, что бинарное дерево поиска это то, что вы после этого. Лучший способ хранить эту информацию будет в виде дерева, где каждый последующий узел на дереве является один символом, и читать путь к конечному узлу дает написание этого слова. Вы бы также необходимо добавить маркер, чтобы указать слово-окончание.

Например: скажите ваш словарь есть такие слова: автомобиль, телеги, кошка, чашка, вырезать

- C
  - A
    - R
      - end
      - T
    - T
      - end
  - U
    - P
      - end
    - T
      - end

Проверка, если слово существует, это вопрос, глядя на каждую букву по отдельности, и что она существует в детях текущего узла.

Check for "cat"
Does "C" exist at the root level? Yes, move to the next letter.
Does "A" exist underneath C? Yes, move on.
Does "T" exist underneath A? Yes, move on.
Is there a word ending after the T? Yes. Word exists.

Check for "cu"
Does "C" exist at the root level? Yes, move to the next letter.
Does "U" exist at the root level? Yes, move to the next letter.
Is there a word ending after the U? No. Word does not exist.

Как вы храните эту информацию до вас. Как Стивен указал вне, троичный поиск Trie может быть путь: каждый узел будет иметь 27 возможных дочерние узлы.

Ответил 05/12/2008 в 04:16
источник пользователем

голоса
3

Вы мертвы-набор на использование двоичного дерева поиска? Фильтр Блума , вероятно , будет более эффективной структурой данных.

Ответил 05/12/2008 в 04:34
источник пользователем

голоса
0

Видя, что это домашнее задание вопрос я буду считать, что вы должны использовать обычный старый бинарное дерево (нет красно-черные деревья, AVL деревья, Radix деревья и т.д.). Ответ то, чтобы попытаться сохранить дерево сбалансированным, как вы строите его из списка слов. Один из подходов заключается в рандомизации список перед чтением его, это дает неплохие результаты. Но вы можете получить лучшие результаты, если вы закажете последовательность ввода (используя такое же сравнение, как то, что использует дерево), а затем рекурсивно подразделяют на вход возвращающегося средней точки, пока элементы не остаются. Результат является сбалансированным деревом.

Я постучала три различных способа сделать это в C #:

private static IEnumerable<T> BinaryTreeOrder<T>(IList<T> range, int first, int last)
{
  if (first > last)
  {
    yield break;
  }

  int mid = (first + last) / 2;
  yield return range[mid];
  foreach (var item in BinaryTreeOrder(range, first, mid - 1))
  {
    yield return item;
  }
  foreach (var item in BinaryTreeOrder(range, mid + 1, last))
  {
    yield return item;
  }    
}

private static void BinaryTreeOrder<T>(IList<T> range, int first, int last, 
                                       ref IList<T> outList)
{
  if (first > last)
  {
    return;
  }

  int mid = (first + last) / 2;
  outList.Add(range[mid]);
  BinaryTreeOrder(range, first, mid - 1, ref outList);
  BinaryTreeOrder(range, mid + 1, last, ref outList);
}

private static void BinaryTreeOrder<T>(IList<T> range, int first, int last, 
                                       ref BinaryTree<T> tree) where T : IComparable<T>
{
  if (first > last)
  {
    return;
  }

  int mid = (first + last) / 2;
  tree.Add(range[mid]);
  BinaryTreeOrder(range, first, mid - 1, ref tree);
  BinaryTreeOrder(range, mid + 1, last, ref tree);
}
Ответил 20/04/2011 в 21:27
источник пользователем

голоса
1

Этот сайт должен помочь вам он имеет реализацию в Java.

Ответил 12/06/2011 в 04:07
источник пользователем

голоса
0

Как предложен Trie будет более эффективной, чем бинарное дерево, но вы можете использовать HashMap и хэш каждого слова. У вас есть небольшой словарь (1000 записей). Как вы траверс документа, проверьте, если слова в HashMap. Если это не так, то предполагается, что слово будет неправильно.

Это не даст вам возможную коррекцию к неправильно написанному слову. Он просто говорит вам, да или нет (правильно или нет).

Если вы хотите, орфографические предложения для неправильных слов, которые вы можете начать с этим слова в файле, а затем генерировать все слова 1 редактировать расстояние и добавить их как ребенок исходного слова. Таким образом, вы строите график. Go 2 уровня вложенности максимальной скорости против точности. При создании узла слова, которое в словаре, вы можете добавить его в список возможных предложений. В конце концов, возвращает список возможных предложений.

Для лучшего проверки орфографии, а также попытаться добавить в фонетическом соответствии.

море йух -> см Ях

Этот метод (создания графиков строк 1 редактировать прочь) является «медленным». Но это хорошее академическое упражнение. Время воспроизведения является O (N ^ ветви).

Если интересно здесь ссылку на один я построил сам (для удовольствия): https://github.com/eamocanu/spellcheck.graph

Некоторые примеры графиков: https://github.com/eamocanu/spellcheck.graph/tree/master/graph%20photos

Я также добавил компонент пользовательского интерфейса к нему, который генерирует графики. Это внешняя библиотека.

Ответил 15/12/2011 в 22:26
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more