Считайте частоту слов огромного текстового файла

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

Мой подход:

  1. Сортировка данного файла - внешний вид
  2. Считайте частоту каждого слова последовательно, сохраните счет в другом файле (вместе со словом)
  3. Сортировка выходного файла по частоте - внешняя сортировка.

Я хочу знать, есть ли лучшие подходы к этому. Я слышал о хэш-таблицах на основе дисков? или B +, но никогда не пробовали их раньше.

Примечание. Я видел похожие вопросы, заданные в SO, но ни один из них не должен решать проблему с данными, большими, чем память.

Изменить. Основываясь на комментариях, согласился, что словарь на практике должен вписываться в память современных компьютеров. Но давайте возьмем гипотетический словарь слов, который достаточно огромен, чтобы не вписываться в память.

5
nl ja de
если вы просто хотите подсчитать слова, вы можете прочитать файл по очереди или потоком файлов. Вам не нужно загружать весь файл в ОЗУ.
добавлено автор Raptor, источник
на каком языке программирования вы работаете?
добавлено автор Raptor, источник
Все разные слова еще больше, чем RAM?
добавлено автор xvorsx, источник
Ну, в этом случае огзд дает хороший ответ ниже: нарежьте его!
добавлено автор Mörre, источник
В самом деле? Сколько оперативной памяти? Даже полный словарь вписывается в сегодняшние компьютеры RAM ...
добавлено автор Mörre, источник
@ vikky.rk Вопрос был не в том, что одно слово будет вписываться в память, но если будет список уникальных слов.
добавлено автор Matteo, источник
На практике да словарь должен соответствовать, но скажите словарь, если он достаточно большой, чтобы не вписываться в память, я хочу знать, какой подход будет лучше
добавлено автор vikky.rk, источник
Да, количество уникальных слов больше, чем размер ОЗУ. Поэтому, если у меня есть хеш-таблица, она не поместится в памяти
добавлено автор vikky.rk, источник
@xvorsx: ни одно слово больше, чем ОЗУ, если это то, о чем вы спрашиваете.
добавлено автор vikky.rk, источник
@ShivanRaptor: Java
добавлено автор vikky.rk, источник
Сколько разных слов есть в файле? Поместили бы они в память, если вы не храните дубликаты?
добавлено автор comocomocomocomo, источник

4 ответы

Я бы пошел с подходом map :

  1. Распределите текстовый файл на узлах, предполагая, что каждый текст в узле может поместиться в ОЗУ.
  2. Рассчитайте каждую частоту слов в узле. (используя хэш-таблицы )
  3. Соберите каждый результат в главном узле и объедините все его.
13
добавлено
Сортируйте каждый файл результата индивидуально, затем откройте их все и прочитайте по строкам, решив, добавить ли результаты (то же слово) и/или, в зависимости от последовательности в алфавите, какую пару слов/nr записать в файл результатов.
добавлено автор Mörre, источник
Поскольку плакат утверждает, что даже словарь слов, используемых в файле, не помещается в его маленькую RAM (???), я голосую +1 над этим решением - и это также работает, когда есть только одна машина, когда вы делаете фрагменты последовательно.
добавлено автор Mörre, источник
Я думал об этом подходе последовательно, но как бы я мог эффективно объединить результаты?
добавлено автор vikky.rk, источник
Да, это почти то, что делает внешний вид. За исключением того, что нам не нужно сортировать весь файл, достаточно просто отсортировать фрагменты.
добавлено автор vikky.rk, источник

Все уникальные слова, вероятно, вписываются в память, поэтому я бы использовал этот подход:

  • Create a dictionary (HashMap).
  • Read the huge text file line by line.
  • Add new words into the dictionary and set value to 1.
  • Add 1 to the value of existing words.

После того, как вы проанализировали весь огромный файл:

  • Сортировка словаря по частоте.
  • Напишите в новый файл отсортированный словарь со словами и частотой.

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

5
добавлено
@Matteo: Я не предлагаю использовать класс Dictionary . Помимо устаревания, он также является абстрактным классом и бесполезен. Выбор слова dictionary основан на использовании HashMap .
добавлено автор Sani Singh Huttunen, источник
нет ... Сортировка словаря после добавления всех слов.
добавлено автор Sani Singh Huttunen, источник
Почему Dictionary ? Класс отмечен как устаревший.
добавлено автор Matteo, источник
хороший подход. но вы бы отсортировали словарь между каждым словом? это приводит к более быстрому поиску будущих слов?
добавлено автор Fredrik, источник
Предполагая, что большинство слов не дублируются. Будет ли этот подход работать нормально при чтении содержимого файла размером 1 Pebibyte (PiB)?
добавлено автор hemanto, источник

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

2
добавлено
Круто, я попробую.
добавлено автор vikky.rk, источник

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

Затем вы можете сортировать записи хэш-таблицы по количеству вхождений.

1
добавлено
pro.jvm
pro.jvm
3 503 участник(ов)

Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш сайт: projvm.com projvm.ru Наш канал: @proJVM Вакансии: @jvmjobs Конфы: @jvmconf

Java & Co
Java & Co
2 370 участник(ов)

Можно обсуждать с матом и без всё, что касается жабы, вплоть до холиваров. НЕ ИМЕЕТ ОТНОШЕНИЯ К САЙТУ JAVARUSH.RU ПРАВИЛА - https://t.me/javarush/75723 Вакансии сюда - https://telegram.me/joinchat/B7IzvUCnfo6d8t3yIxKguQ По вопросам - @thedude

learn.java
learn.java
1 888 участник(ов)

Чат для начинающих и не только Статистика: https://combot.org/chat/-1001083535868 Основной чат - @jvmchat

Java Underground
Java Underground
169 участник(ов)

https://vk.com/javatutorial

Javanese Questions
Javanese Questions
109 участник(ов)

Чат предназначен для обмена знаниями строго в формате в вопрос-ответ. Тема — Java, Kotlin и Android. Вопрос должен быть предварительно прогуглен, понятно и грамотно сформулирован, помечен хэштегами. Ответ — тем более. Куски кода размером в несколько строк можно писать прямо здесь, для больших кусков кода стоит использовать http://gist.github.com/, http://pastebin.com/, https://codeshare.io/ или любой аналогичный сервис. В некоторых случаях можно прикреплять скриншоты. Стикеры и гифки запрещены. Дополнять и уточнять вопросы и ответы — редактированием исходного сообщения. Обсуждения должны приводить к редактированию вопроса/ответа и удаляться. По хештегам можно искать существующие вопросы и овтеты: #вопрос #ответ #git #generics #java #server #awt #javafx #swing #kotlin #anko #tornadofx #ktor #android #recyclerView #performance #arch #network #permissions #storage #async