20
Впринципе на пхп много реализаций, а на С я еще не видел. Пользуйтесь
PHP
<?php
Class MarkovChains
{
var $prepared = array();
function MarkovChains($source)
{
$source = strtolower($source);
$source = str_replace(array («? «, «! «), «.», $source);
$source = str_replace(array (» -», «- «, «\t», «\r», «\n», «|», «&», ‘\\’, ‘/’, » :», » ;», «©», «·»), ‘ ‘, $source);
$source = str_replace(array («)», «(«, «]», «[", "'", "\"", '*', '•', '~', '{', '}'), '', $source);
$source = str_replace(" ,", ",", $source);
$source = preg_replace("~(\s+\d{1,2}\s+)|(\w*\.\w+)~", " ", $source);
$source = preg_replace("~\s+~", " ", $source);
$sentens = explode('. ', $source);
$count_sentens = count($sentens);
for ($j=0; $j<$count_sentens; ++$j)
{
$sentens[$j] = explode(‘ ‘, $sentens[$j]);
$count_words = count($sentens[$j]) – 1;
for ($i=0; $i < $count_words; ++$i)
{
$prefix = $sentens[$j][$i];
$this->prepared[$prefix][] = $sentens[$j][$i+1];
}
}
$keys = array_keys($this->prepared);
foreach ($keys as $key)
{
$this->prepared[$key] = array_unique($this->prepared[$key]);
}
}
function GenerateText($size)
{
$result_count = 0;
for ($j=0; $result_count < $size; ++$j)
{
$prev = array_rand($this->prepared);
$num = mt_rand(5, 12);
for ($i=0; $i<$num; ++$i)
{
$sents[$j][$i] = $prev;
++$result_count;
$p = $this->prepared[$prev][mt_rand(0, count($this->prepared[$prev]) – 1)];
if ($p == ») $p = array_rand($this->prepared);
$prev = $p;
if ($prev == ») break 2;
}
}
foreach ($sents as $sent)
{
$count_word=count($sent);
if ($count_word<=2) continue;
if (strlen($sent[$count_word-1]) < 4) unset($sent[$count_word-1]);
$sent[$count_word-2] = rtrim($sent[$count_word-2], «,:;»);
$sent[$count_word-1] = rtrim($sent[$count_word-1], «,:;»);
$output .= ucfirst(implode(‘ ‘, $sent)).’. ‘;
}
$output = str_replace(‘ .’, ‘.’, $output);
return $output;
}
}
//Example
$source = «»;
//file_get_contents(«text.txt»);
$markov = new MarkovChains($source);
$result = $markov->GenerateText(500);
echo $result;
?>
На Си
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char inputchars[4300000];
#define MAXWORDS 800000
char *word[MAXWORDS];
int nword = 0;
int k = 2;
int next[MAXWORDS];
#define NHASH 499979
int bin[NHASH];
#define MULT 31
unsigned int hash(char *ptr)
{ unsigned int h = 0;
unsigned char *p = ptr;
int n;
for (n = k; n > 0; p++) {
h = MULT * h + *p;
if (*p == 0)
n–;
}
return h % NHASH;
}
int wordncmp(char *p, char* q)
{ int n = k;
for ( ; *p == *q; p++, q++)
if (*p == 0 && –n == 0)
return 0;
return *p – *q;
}
int sortcmp(char **p, char **q)
{ return wordncmp(*p, *q);
}
char *skip(char *p, int n)
{ for ( ; n > 0; p++)
if (*p == 0)
n–;
return p;
}
int main()
{ int i, wordsleft = 10000, j;
char *phrase, *p;
word[0] = inputchars;
while (scanf(«%s», word[nword]) != EOF) {
word[nword+1] = word[nword] + strlen(word[nword]) + 1;
nword++;
}
for (i = 0; i < k; i++)
word[nword][i] = 0;
for (i = 0; i < NHASH; i++)
bin[i] = -1;
for (i = 0; i <= nword – k; i++) { /* check */
j = hash(word[i]);
next[i] = bin[j];
bin[j] = i;
}
for (i = 0; i < k; i++)
printf(«%s\n», word[i]);
phrase = inputchars;
for ( ; wordsleft > 0; wordsleft–) {
i = 0;
for (j = bin[hash(phrase)]; j >= 0; j = next[j])
if ((wordncmp(phrase, word[j]) == 0)
&& (rand() % (++i) == 0))
p = word[j];
phrase = skip(p, 1);
if (strlen(skip(phrase, k-1)) == 0)
break;
printf(«%s\n», skip(phrase, k-1));
}
return 0;
}
Комментарии
-
Hitman95 пишет:
Интересно…..
Оставьте свой отзыв
Вы должны войти, чтобы оставлять комментарии.
