SnapSh0t
@SnapSh0t
iOS-Developer

Какой алгоритм использовать для нахождения повторяющихся слов в строке?

Здравствуйте, друзья!

Подскажите алгоритм для нахождения повторяющихся слов в строке.

P.S. для небольшого количества слов можно записать двойной цикл для сравнения, но такой подход является неэффективным для большого количества слов - он не подходит для одного миллиона слов и т.д.
  • Вопрос задан
  • 1224 просмотра
Решения вопроса 1
Neuroware
@Neuroware
Программист в свободное от работы время
Задача поставлена странно, во первых ни в одном языке нет миллиона слов, а используется в среднем от 3 до 10 тыс. То есть задача для миллиона в корне неверна. В любом случае как минимум 1 проход потребуется в любом случае, я бы сделал так.
1. Создание dictionary слов и их количества
2. Проход по очереди всех слов
3. Поиск текущего слова в списке, если его там нет добавляем в список и количество выставляем в 1, если есть +1 к количеству

В итоге получаем 1 проход по всему тексту и обращение по индексу к dictionary, которое стоит относительно дешево, намного дешевле перебора всего списка.

Похожий подход применял для анализа текстов, в итоге для 20 книг ~500 стр каждая уходило около 3-5 секунд.
Для C# это выглядит так
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
@mib
Можно использовать наивный метод: в базе данных создать таблицу `table`: `word`|`count_words` (primary key `word`). Потом брать все слова по порядку, и добавлять в таблицу. Если такое слово уже есть - увеличивать его количество повторений на 1, примерно так:
INSERT INTO `table` (`word`) VALUES ('$new_word') ON DUPLICATE KEY UPDATE `count_words`=`count_words`+1;

В любом языке не так уж много слов, ну к примеру 50 000, а тескт может быть сколь угодно большим.

А потом сделать выборку, сортированную по количеству повторений.
То-же самое можно сделать без базы данных, при помощи хешей: слово переводить в транслит, и увеличивать счетчик соотв хеша.
Ответ написан
gbg
@gbg
Любые ответы на любые вопросы
Сразу нужны уточнения - помещается ли строка в RAM?

Если помещается - за первый проход можно найти концы всех слов (положения всех пробелов в строке).

Это получится список отрезков (начал и концов слов)

Этот список сортируем по длине слов.

Получим список, в котором подряд будут идти слова равной длины.

Потом каждый кластер в этом списке сортируем в лексикографическом порядке. И считаем отсортированные дубли.

Задача прекрасно подходит для параллельной обработки.
Ответ написан
dimonchik2013
@dimonchik2013
non progredi est regredi
я извиняюсь, а
(\w+) \1
чем не подходит?
слова идут не подряд?
тогда строку в массив, сорт и ..
Ответ написан
uvelichitel
@uvelichitel
habrahabr.ru/users/uvelichitel
Фильтр Блума
Ответ написан
Комментировать
@SeptiM
А префиксное дерево не подойдет? Я бы сначала убрал бы все знаки препинания, понизил регистры, а потом его построил. Можно в каждой вершине хранить число листьей в поддереве и находить за O(1/phi) все слова, которые встречаются хотя бы phi * n раз, где n -- число всех слов.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы