Структура данных Решение о расчете эффективной частоты

Вопрос.Какая структура данных более эффективна при вычислении n наиболее часто встречающихся слов в текстовом файле. Хэш-таблицы или Приоритетные очереди?

Ранее я задавал вопрос, связанный с этой темой, однако после творческих ответов я запутался и выбрал два типа данных, которые мне действительно легко реализовать; Хэш-таблица и приоритетные очереди

Путаница с приоритетными очередями:Честно говоря, я слушал лекцию на YouTube, посвященную приоритетным очередям, понял, что это каждый компонент, однако, когда дело доходит до его применимости, я запутался. Используя бинарную кучу, я могу легко реализовать приоритетную очередь, однако моя проблема заключается в том, чтобы сопоставить использование ее компонентов с проблемой частоты.

Идея моей хеш-таблицы:Поскольку здесь решение о размере хеш-таблицы было немного неопределенным, я решил использовать то, что мне кажется более разумным: 26. Из-за количества букв в алфавите. Кроме того, с хорошей хэш-функцией это было бы эффективно. Однако повторное обращение к связанным спискам (используя отдельную цепочку для сговора) и увеличение его целочисленного значения на 1, на мой взгляд, было бы неэффективным.

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


person Ali    schedule 20.04.2012    source источник
comment
Я думаю, что хэш-таблица настолько хороша, насколько это возможно.   -  person usr    schedule 21.04.2012
comment
@usr Спасибо за комментарий! Можете ли вы также дать мне идею/критику/посоветовать, является ли моя идея хеш-таблицы реализовать ее с размером 26 из-за размера алфавита хорошей идеей?   -  person Ali    schedule 21.04.2012
comment
@rolandbishop Я согласен на использование хеша. Поскольку распределение первых букв слов в английском языке неравномерно, выбор хэш-функции, которая помещает слова в 26 ячеек, был бы плохим выбором. Даже если бы распределение было равномерным, это слишком мало ячеек. Ознакомьтесь с этим предыдущим обсуждением от SO на тему «Какая хорошая хеш-функция для английского языка слова'.   -  person vpiTriumph    schedule 21.04.2012


Ответы (2)


Хеш-таблица была бы более быстрой из двух предлагаемых вариантов, кроме того, она имела бы больше смысла. Вместо того, чтобы выбирать размер 26, если у вас есть оценка общего количества уникальных слов (а словарный запас большинства людей за пределами технических специализированных терминов ненамного превышает 10 000 — 20 000 — это действительно много, а 30 000 — для людей, которые составляют хобби собирать слова), сделайте размер достаточно большим, чтобы вы не рассчитывали когда-либо его заполнить, чтобы вероятность столкновения была низкой - не более 25%. Если вы хотите быть более консервативным, реализуйте функцию для перефразирования содержимого таблицы в таблицу в два раза больше исходного размера (и сделайте размер простым, поэтому только примерно в два раза больше исходного размера).

Теперь, поскольку он помечен как C++, вы можете спросить себя, почему вы просто не используете мультимножество прямо из стандартной библиотеки шаблонов. Он будет вести подсчет того, сколько каждого слова вы введете в него.

В любом случае вам нужно будет сделать отдельный проход, чтобы найти, какое из слов является n наиболее частым, поскольку у вас есть только частоты, а не порядок частот.

person DRVic    schedule 21.04.2012
comment
У меня есть несколько вопросов. 1) Использование предложенного вами «мультиэта» по-прежнему потребует O (n) времени для подсчета частот, верно? 2) Существуют ли какие-либо различия между «multiset» и «std::map», использующими карту как ‹word, word-frquency›? - person Ali; 21.04.2012
comment
+1 Верно. Есть N слов, и каждое нужно найти в таблице. Так как хеш-таблица — это O(1), то и все это — O(N). Затем ему просто нужно сохранить в хеш-таблице структуру пословно, чтобы у него было место для увеличения счетчика. - person Mike Dunlavey; 21.04.2012
comment
При использовании хеш-таблицы второй проход для поиска наиболее частых n должен тратить время на проверку всех записей, которые все еще пусты, что стоит определенных затрат. Вероятно, не так много, как N log N, где N — размер ввода. Но, возможно, в зависимости от размера стола. С точки зрения асимптотической стоимости хэш-таблица может быть быстрее, чем мультимножество (или даже карта‹слово, количество›) — в зависимости от того, насколько хорошо оптимизирован размер таблицы. На самом деле это непонятно, так как мы даже не знаем размер текстового файла. А мультисет дает ответ самым прямым образом. - person DRVic; 23.04.2012
comment
Что касается разницы между multiset и std::map‹ word, int ›, насколько я могу судить, одной разумной реализацией multiset был бы тип std::map‹, int ›. Я не знаю никакой разницы, кроме интерфейса. - person DRVic; 23.04.2012

Почему бы вам не использовать универсальную/универсальную функцию хеширования строк? В конце концов, вы не хотите считать первую букву, вы хотите пересчитать все возможные слова. Я бы держал подсчет ведра динамическим. Если нет, вам нужно будет делать безумное количество обходов связанных списков.

person usr    schedule 21.04.2012
comment
Не могли бы вы сказать мне, с точки зрения частоты подсчета, будет ли эффективность хэш-таблицы (даже если она хорошо реализована) такой же, как у простого 'std::map'? - person Ali; 21.04.2012
comment
Это нужно измерить. Я предполагаю, что обычная хеш-таблица с автоматическим изменением размера и внутренним связыванием будет оптимальной. Насколько я знаю, это золотой стандарт хеш-таблиц. - person usr; 21.04.2012