Простой генератор текста с помощью цепей Маркова
Вот здесь мы делали на C++ достаточно сложный проект для генерации текста с помощью цепей Маркова, на днях понадобилось что-то попроще, приведу мини-проект из одной функции на PHP.
Обычно подобная программа для цепей Маркова разбивает входной текст на цепочку токенов-слов,
затем, перемещаясь по ним в некотором окне фиксированного размера,
сохраняет первые $keySize
слов в качестве префикса, и добавляет ($keySize+1
)-ое слово,
выбранное из набора соответствующих префиксу суффиксов.
Конечно, пределов совершенству нет, и мы вполне могли делать первые буквы предложений большими, убирать лишние знаки препинания и т.п., но всё это сразу же усложнило бы код. Путь к написанию подобного проекта можно посмотреть, например, на этой странице.
Скрипт выполнялся на локальном хосте XAMPP с PHP 8.X, исходный файл data.txt
("Колобок") также прикреплён ниже.
<?php function markovChainTextGenerator ($text, $keySize, $maxWords) { //текст, размер ключа в словах, общее кол-во слов $maxlen = 30; //макс. длина слова //Создать массив токенов: $token = []; $position = 0; $maxPosition = mb_strlen ($text, 'UTF-8'); while ($position < $maxPosition) { if (preg_match('/^(\S+)/', mb_substr($text, $position, $maxlen, 'UTF-8'), $matches)) { $token[] = $matches[1]; $position += mb_strlen($matches[1], 'UTF-8'); } elseif (preg_match('/^(\s+)/', mb_substr($text, $position, $maxlen, 'UTF-8'), $matches)) { $position += mb_strlen($matches[1], 'UTF-8'); } else { die( 'Неизвестный токен в позиции ' . $position . ': ' . mb_substr($text, $position, $maxlen, 'UTF-8') . '...' . PHP_EOL); } } //Создать словарь: $dictionary = []; for ($i = 0; $i < count($token) - $keySize; $i++) { $prefix = ''; $separator = ''; for ($c = 0; $c < $keySize; $c++) { $prefix .= $separator . $token[$i + $c]; $separator = '.'; } $dictionary[$prefix][] = $token[$i + $keySize]; } //Начальный токен: function getStartToken(&$token,$keySize) { $rand = rand (0, count($token) - $keySize); $startToken = []; for ($c = 0 ; $c < $keySize ; $c++) { array_push ($startToken, $token[$rand + $c]); } return $startToken; } //Создать текст: $startToken = getStartToken($token,$keySize); $text = implode(' ', $startToken); $words = $keySize; do { $tokenKey = implode ('.', $startToken); if (!array_key_exists($tokenKey,$dictionary)) { $startToken = getStartToken ($token,$keySize); continue; } else { $rand = rand (0, count($dictionary[$tokenKey]) - 1); $newToken = $dictionary[$tokenKey][$rand]; } $text .= ' ' . $newToken; $words++; array_shift ($startToken); array_push ($startToken, $newToken); } while ($words < $maxWords); return $text; } srand(time()); $text = markovChainTextGenerator( file_get_contents(__DIR__ . '/data.txt'), 3, 300); echo wordwrap ($text, 100, '<br>'.PHP_EOL) . PHP_EOL; ?>
Файл data.txt, кодировка Юникода UTF-8 (4 Кб)
Пример вывода скрипта:
ушёл, Я от волка ушёл, От тебя, зайца, не хитро уйти! И покатился себе дальше; только волк его и видел!.. Катится колобок, а навстречу ему лиса: «Здравствуй, колобок! Какой ты хорошенький». А колобок запел: Я по коробу скребён, По сусеку метён, На сметане мешон, Да в масле пряжон, На окошке стужон; Я от дедушки ушёл, Я от бабушки ушёл, Я от зайца ушел, От тебя, волка, не хитро уйти! И опять укатился; только медведь его и видел!.. Катится колобок, а навстречу ему медведь: «Колобок, колобок! Я тебя съем». — «Не ешь меня, серый волк! Я тебе песенку спою!» Я по коробу скребён, По сусеку метён, На сметане мешон, Да в масле пряжон. На окошке стужон; Я от дедушки ушёл, Я от волка ушёл, От тебя, лиса, и подавно уйду! «Какая славная песенка! — сказала лиса. — Но ведь я, колобок, стара стала, плохо слышу; сядь-ка на мою мордочку да пропой еще разок погромче». Колобок вскочил лисе на мордочку и запел ту же песню. «Спасибо, колобок! Славная песенка, еще бы послушала! Сядь-ка на мой язычок да пропой в последний разок», — сказала лиса и высунула свой язык; колобок прыг ей на язык, а лиса — ам его! и скушала. бабушки ушёл, Я от зайца ушёл, Я от зайца ушёл, Я от зайца ушёл, Я от зайца ушёл, Я от бабушки ушёл, Я от зайца ушёл, Я от бабушки ушёл, Я от зайца ушёл, Я от бабушки ушёл, Я от зайца ушёл, Я от бабушки ушёл, Я от зайца ушёл, Я от бабушки ушёл, Я от зайца ушел, От тебя, волка, не хитро уйти! И покатился себе дальше; только заяц его и видел!.. Катится колобок, а навстречу ему заяц: «Колобок, колобок! Я тебя съем». — «Не ешь меня, серый волк! Я тебе песенку спою», — сказал колобок и запел: Я по коробу
20.11.2021, 08:08 [948 просмотров]