Дано много-много статей и комментариев к ним, взятых с habrahabr.ru и склеенных в одну большую портянку.
Требуется на основании суммарного текста всех статей сгенерировать новую среднестатистическую статью для Хабра, используя для этого цепи Маркова. То есть сгенерированная статья должна быть человекочитаема. Текст статьи должен быть среднехабровой длинны и разбит на среднехабровые абзацы. Возможно дополнение текста статьи изображениями, различными списками и примерами кода. Следом за статьей должен идти среднестатистический для Хабра поток комментариев, основанный на суммарном тексте всех комментариев к исходным статьям. Имена авторов комментариев также берутся из портянки, даты комментариев генерируются скриптом. Комментарии должны быть вложенными. Свежесгенерированная статья и комментарии к ней должны быть оформлены максимально близко к оригиналу.
Решением данной задачи должен быть скрипт-генератор + сгенерированная статья с комментариями. У генератора должны быть настройки: минимальное и максимальное количество слов в предложении, предложений в абзаце и абзацев в статье.
Программа строит некоторую структуру данных (возможно, вы создадите специально для нее удобный вам класс), которая хранит информацию следующего рода:
- После слов («покой», «нам») с вероятностью 0.7 идет слово «только», с вероятностью 0.3 идет слово «не»
- После слов («нам», «только») с вероятностью 0.4 идет слово «снится», с вероятностью 0.6 идет слово «бы»
- и т.д.
либо:
- После слов («покой», «нам») идут слова («только», «снится», «не», «не», «только», «только», «не», «только», «будет», «только», «сниться» …)
- После слов («нам», «только») идут слова («снится», «бы», «бы», «бы», «снится», «выйти», «не», «бы», «надо», «надо», «надо» …)
- и т.д.
Назовем эту структуру словарем.
Склонения, спряжения и видоизменения слов никак не обрабатываются. Все формы слов считаются разными словами. Все слова приводятся к нижнему регистру. Точка, запятая, двоеточие, вопросительный и восклицательный знаки считаются словами. Все остальные знаки препинания отбрасываются.
Генерация текста начинается с любого на выбор слова из словаря, оно выводится с большой буквы (начинается новое предложение), после которого в зависимости от вероятности выбирается следующее слово и т.д. Если следующее слово выбрать невозможно, ставится точка, начинается новое предложение со случайного слова из словаря. Каждое предложение надо начинать с большой буквы. В обычной ситуации предложение продолжается до тех пор, пока генератор не перейдет в состояние «.». Однако, надо не допускать слишком длинных предложений и ставить точку принудительно, если предложение состоит, например, более чем из 100 слов. Длину предложения можно формировать на основе распределения длины предложений в исходном корпусе текста.
Текст нужно делить на абзацы по предложениям. Сколько будет предложений в абзаце зависит от обрабатываемого корпуса текста. Вычисляется частотность предложений в абзацах в корпусе, например:
- 60% абзацев имеют два предложения.
- 20% – три.
- 15% – шесть.
- 5% – десять.
В зависимости от этих вероятностей высчитывается количество предложений в текущем абзаце.
С цепями Маркова наше приложение роднит то, что в каждый момент времени генератор текста находится в состоянии, которое определяется последним сгенерированным словом и с какой-то вероятностью переходит в новое состояние – следующее слово:
Качество полученного текста в итоге будет зависеть от двух факторов – полноты найденного вами корпуса и алгоритма работы программы. Вы можете самостоятельно внести в вашу программу модификации, позволяющие получать на выходе более качественный текст, например, специальным образом обрабатывать имена собственные.
Для генерирования нового текста и обхода по готовому словарю очень подойдет класс-итератор.
Подробно решение этой задачи на языках С и Java рассмотрено в книге Практика программирования Кернигана и Пайка. Книга очень много раз переиздавалась, ее очень легко найти в сети.