Программа генерации цепей Маркова k-го порядка сможет поместить не более пяти мегабайт входного текста в массив inputchars:
int k = 2
char inputchars[5000000];
char *word[ 1000000 ],
int nword = 0;
Алгоритм Шеннона можно реализовать непосредственным поиском по всему тексту, хотя он и может оказаться неэффективным для больших объемов. Вместо этого мы задействуем массив word, аналогичный массиву остатков за исключением того, что его элементы всегда указывают на начала слов (типичная модификация). В переменной nword хранится количество слов. Файл считывается следующим кодом:
word[0] = inputchars
while scanf("%$>". word[nwordl) != EOF
word[nword+l] - word[nword] + strlen(word[nword!) + 1 nword++
Все слова добавляются к массиву inputchars (дополнительной памяти под них отводить не нужно), а завершаются слова символом \0, добавляемым функцией scanf автоматически.
После считывания исходного текста мы отсортируем массив word, чтобы все элементы, указывающие на последовательности с одинаковым началом, оказались рядом. Функция wordncm р из листинга 15.9 осуществляет сравнение последовательностей слов.
Листинг 15.9. Сравнение последовательностей слов
int wordncmp(char *р, char* q) n = k
for ( t *p == *q: p++. q++) if (*p == 0 && --n =*= 0) return 0. return *p - *q
Строки сравниваются до тех пор, пока их символы совпадают. При достижении символа \0 счетчик п уменьшается на 1, а после обнаружения к одинаковых слов происходит выход из функции, Если обнаруживаются различия, функция возвращает разность строк.
Считав текст, мы добавим к нему к символов \0, чтобы функция сравнения не дала сбоя в конце массива, выведем первые к слов документа (чтобы инициализировать наш генератор), а затем вызовем функцию сортировки.
Листинг 15.10. Вызов функции сортировки для массива остатков
for 1 = [0. к)
word[nword][i] = О for п = [0. к) print word[i] qsort(word, nword, sizeofCword[0])t sortcmp)
Функция sortcmp, как и раньше, добавляет «уровень косвенности» к указателям.
Наша эффективно использующая память структура содержит большой объем информации о содержащихся в тексте k-граммах. Если к ==1 и на вход подан текст «о/ the people, by the people, for the people», массив word может выглядеть следующим образом:
word[0]: by the wordfl]: for the word[2]: of the word[3]: people word[4]: people, for word[5]: people, by word[6]: the people, word[7]: the people word[8]: the people,
Для простоты в этом списка показаны только первые к+1 слово из всей строки, на которую указывает элемент массива. Если нам нужно продолжить фразу, заканчивающуюся словом the, мы обратимся к массиву остатков и получим три возможных варианта: два «people,» и один «people».
Теперь мы можем генерировать абракадабру с помощью приведенного в листинге 15.11 псевдокода.
фраза = первая фраза входного массива
цикл
ищем фразу в массиве word[0..nword-1] с помощью двоичного поиска из всех фраз с первыми к одинаковыми словами выбираем одну, на которую
указывает р
фраза = слово, следующее за р если k-е слово фразы имеет длину О выход
вывод к - г о слова фразы
ЦИКЛ инициализируется присваиванием переменной фраза первых символов входного текста (вспомните, что эти символы уже выведены в выходной файл). Двоичный поиск (программа из раздела 9.3) позволяет найти первое вхождение фразы в массиве остатков (важно найти именное первое вхождение, а программа из раздела 9.3 ориентирована именно на это). В следующем цикле проверяются все равные фразы, а решение 12.10 используется для случайного выбора одой из них. Если k-е слово этой фразы имеет нулевую длину, эта фраза является последней в документе, поэтому цикл заканчивается.
В листинге 15,12 приведен полный текст псевдокода, реализующего эти идеи и вводящего ограничение на количество порождаемых слов.
Опубликовал vovan666
April 17 2013 00:04:54 ·
0 Комментариев ·
4342 Прочтений ·
• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •
Комментарии
Нет комментариев.
Добавить комментарий
Рейтинги
Рейтинг доступен только для пользователей.
Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.
Нет данных для оценки.
Гость
Вы не зарегистрированны? Нажмите здесь для регистрации.