Depois do famoso lero-Lero Generator, grande amigo dos memorandos, e-mails para clientes e trabalhos de faculdade, eis mais uma arma acadêmica:
SCIgen - An Automatic CS Paper Generator
Aproveitem e leiam um paper que publiquei recentemente:
Depois do famoso lero-Lero Generator, grande amigo dos memorandos, e-mails para clientes e trabalhos de faculdade, eis mais uma arma acadêmica:
SCIgen - An Automatic CS Paper Generator
Aproveitem e leiam um paper que publiquei recentemente:
heehehhehe muito bom! Não tinha visto ainda…
Bom, o seu paper só tinha esse probleminha… acho que alguém (não Chomsky, que continua vivo e incomodando um monte de gente) não pôde investigar a configuração ortogonal nessa época.
Excelente !!! :lol:
Há muito que não ria tanto. O pior é que se eu espalhar um destes leros no meu trabalho, vai todo mundo me dar os parabéns …
Uma vez eu tinha feito o seguinte:
Baixei os RFCs em formato texto. (Dá para obtê-los de www.rfc-editor.org)
Escrevi um programa que lia todos eles, e determinava algumas distribuições estatísticas do tipo “se a palavra X ocorre no texto, a palavra Y a precede com uma freqüência Z”.
Então, com esses dados, criava alguns textos aleatórios mas usando a mesma distribuição de freqüências.
Dava alguns textos bastante malucos também.
Mas esse gerador que o Shoes apresentou é bastante estruturado, dá para fingir bem. (se você rodar esse gerador algumas vezes, dá para perceber que a estrutura é fixa, tal como os papers que devem ser submetidos.)
Olá
[]s
Luca
Um exemplo da saída desse gerador que escrevi faz algum tempo (sorry, é em C++, e vi que ele não quebrava as linhas em sentenças direito. Mas veja o que é possível fazer apenas com estatística )
The measures enhances rather than Network Graphics by
the response.
When aborting the last to it can be used to a which have
been discussed..
Note that requiring other type code
For example, we send a Hello message assigned, none
Obsoletes: Joe NSW Protocol 26 C.
FIN-WAIT-1 STATE DIAGRAMS Here was put up parameters x0,
followed by Butler, should be found in response and the
number in response, and including entry, command to send
packet that at CCN that the old packets from NGP could
be composed of the contents and sent to half:.
rrr T
NRTC-NET Northrop Research Network GEOF Geoff DARCOM-KA.
Console for ASCII type of bit-mapped graphics
functionality and ABORT command language designers to
its value for class 3 19 NBS MD or can then either
absolute and reissued as a postal and RFC 698,.
18, 54: a host names and discussion will communicate
more internet system were experienced user may be
incorporated into machine code 33 Oxford Street
Cambridge, if it encourages the graph is, i.
Ronald L, Message Formats ------------------------------
---------- -------------
STATUS: address-list any-name path between the group or
algorithm, 8 3..
McKenzie, 500-505, or the transit at the FDB.
That is simply duplicating each pseudo- typewriter
version number in the first file name server TELNET
connections which contains address field.
I do the byte Meaning: The following functions and may
be designed to a buffer? Would be regarded as the
control information with some number 0..
Os Lábios da compressão cerrada, que adejava com a seu
ser ouvido: - Decidi fazer-vos mal. O chão; disse-lhe
que levaria a doçura: - O Felisberto, a Natividade
repreendeu a tempo, o patrão, sentada, mas deixou-me
outra a cúpula oval de levar em tal hipótese. Clínica e
a senhora que lá de seu agudo: - Esta esplêndida galeria
de todo o supunha Mr.. - Pois não se lhes não o ventre
para dizer às multidões! Fingiu que fazia com a fio a
acolheram Pereira de ter, uma das outras necessitadas..
Além disso e da amiga, gestos eram toda a casa, apesar
da sacada, ficara de onde estivera na cabana o
esquecimento, e iluminando-se de Aurélia de benjoim;
Félix sorriu tristemente montados; pouco à vontade,
arreios, apoderando-se de história. - Por que um tanto
mais fino lavor o fato - tendo contribuído para receber
corpo, se cá está o jacaré bóia em que por esse mundo
dos pregadores há de noz... Emendava-lhe os guerreiros
que ainda agora irmos assim também de uma cabana do
outro e que se aproximava. A soldadesca pasma! -Morta
podem sair da cabeça no ouvido. Parava às horas e
culturais que mais formosa mulher, mas exceto onde me,
sanãs, constituíam a varanda, mas já era perto da mata e
falou da rua Direita, eram respeitáveis; já das nossas
frontes namoradas daquela miserável que faz ganhar
terreno amigo, -seu primo.
O mesmo programa, agora alimentado com o texto de alguns livros em português.
Suspeito que o povo da minha faculdade use algum sistema parecido para geração de artigos. Mero palpite, vou investigar
Essa é de autoria própria :mrgreen:
Filosofia heheheh. @+ Quero ver alguém contra-argumentar uhauhahuauha!!
Thingol, vc usou o algoritmo da cadeia de Markov, ou algum outro esquema?
[quote=renato3110]Essa é de autoria própria :mrgreen:
Filosofia heheheh. @+ Quero ver alguém contra-argumentar uhauhahuauha!![/quote]
Alias quero ver alguém entender…
É isso mesmo.
Basicamente fiz o seguinte: (em C++ mesmo, mas usando STL):
Varri um arquivo texto, separando-o em palavras;
A freqüência de cada palavra é calculada;
Para cada palavra, calculamos também a freqüência da palavra imediatamente anterior.
Para cada palavra do texto, então, existe uma lista de palavras que podem sucedê-la, cujas freqüências são calculadas. Por exemplo, a palavra “should” foi sucedida, no texto, por “be”, “find” e outras palavras.
Para gerar o texto, fazemos o seguinte:
Escolhemos uma palavra, mas de acordo com a sua freqüência dentro do texto; (É por isso que a primeira palavra normalmente é “The”, se for em inglês, ou “os”, se for em português);
A próxima palavra deve ser escolhida na lista de palavras que podem sucedê-la, e de acordo com sua freqüência.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <hash_map>
//-- Leia um arquivo texto, e use critérios probabilísticos para gerar um outro texto.
//-- Neste caso iremos verificar para cada palavra qual a probabilidade de ela ser seguida por
//-- uma segunda palavra.
//-- As strings não serão repetidas, mas "internalizadas", ou seja,
//-- apenas uma cópia física de cada string aparecerá na memória. Cada string será representada
//-- por um código.
//-- 1) Ler cada palavra e inseri-la em um mapa A (palavra->codigo). Esse mapa será temporário
//-- porque iremos substituí-lo por um vetor B (código->palavra).
//-- 2) Reler o arquivo, usando o mapa A, palavra->código e procedendo como antes.
//-- 3) Duas strings são iguais se seus códigos forem iguais.
using namespace std;
//
//-- Required by hash_map
//
struct hasher
{
enum { bucket_size = 4, min_buckets = 8 };
/** A seguinte função retorna o hash da string. Adaptada da função de hash do MFC */
size_t operator() (const string& s1) const
{
size_t nHash = 0;
for (string::const_iterator p = s1.begin(), p_end = s1.end(); p != p_end; ++p)
nHash = (nHash<<5) + nHash + *p;
return nHash;
}
/** A seguinte função retorna s1 < s2 */
bool operator() (const string& s1, const string& s2) const
{
return stricmp (s1.c_str(), s2.c_str()) < 0;
}
};
typedef hash_map< string,long,hasher > MAP_S_L;
typedef MAP_S_L::iterator MAP_S_L_I;
typedef vector<string> V_S;
typedef vector<long> V_L;
typedef map<long,long> MAP_L_L;
typedef MAP_L_L::iterator MAP_L_L_I;
typedef vector<MAP_L_L> V_MAP_L_L;
typedef multimap<long, long> MMAP_L_L;
typedef MMAP_L_L::iterator MMAP_L_L_I;
typedef map<double,long> MAP_D_L;
typedef MAP_D_L::iterator MAP_D_L_I;
typedef vector<MAP_D_L> V_MAP_D_L;
V_S b;
V_L c; //-- Contagem das ocorrências das palavras, deve ter a mesma dimensão de b
V_MAP_L_L d; //-- Contagem das ocorrências das palavras subseqüentes, deve ter a mesma dimensão de b
MAP_D_L f;
V_MAP_D_L g; //-- Freqüências das ocorrências das palavras subseqüentes, deve ter a mesma dimensão de b
bool ispunctchar (int ch)
{
return ch == '.' || ch == ',' || ch == ':' || ch == ',' || ch == ';' || ch == '!' || ch == '?';
}
bool iswordchar (int ch)
{
//-- Note que todos os caracteres acima de 128 serão considerados alfabéticos
//-- para facilitar.
return 'A' <= ch && ch <= 'Z'
|| 'a' <= ch && ch <= 'z'
|| '0' <= ch && ch <= '9'
|| ch == '_' || ch == ''
|| ch == '-'
|| ch >= 128;
}
int getword (FILE *v, char word[])
{
int ch;
//-- Devemos pular os caracteres não-alfabéticos [^A-Za-z0-9_']
char *p = word;
while ((ch = getc (v)) != EOF && !iswordchar (ch))
{
if (ispunctchar (ch))
{
*p++ = ch;
*p = '[code]
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <hash_map>
//-- Leia um arquivo texto, e use critérios probabilísticos para gerar um outro texto.
//-- Neste caso iremos verificar para cada palavra qual a probabilidade de ela ser seguida por
//-- uma segunda palavra.
//-- As strings não serão repetidas, mas "internalizadas", ou seja,
//-- apenas uma cópia física de cada string aparecerá na memória. Cada string será representada
//-- por um código.
//-- 1) Ler cada palavra e inseri-la em um mapa A (palavra->codigo). Esse mapa será temporário
//-- porque iremos substituí-lo por um vetor B (código->palavra).
//-- 2) Reler o arquivo, usando o mapa A, palavra->código e procedendo como antes.
//-- 3) Duas strings são iguais se seus códigos forem iguais.
using namespace std;
//
//-- Required by hash_map
//
struct hasher
{
enum { bucket_size = 4, min_buckets = 8 };
/** A seguinte função retorna o hash da string. Adaptada da função de hash do MFC */
size_t operator() (const string& s1) const
{
size_t nHash = 0;
for (string::const_iterator p = s1.begin(), p_end = s1.end(); p != p_end; ++p)
nHash = (nHash<<5) + nHash + *p;
return nHash;
}
/** A seguinte função retorna s1 < s2 */
bool operator() (const string& s1, const string& s2) const
{
return stricmp (s1.c_str(), s2.c_str()) < 0;
}
};
typedef hash_map< string,long,hasher > MAP_S_L;
typedef MAP_S_L::iterator MAP_S_L_I;
typedef vector<string> V_S;
typedef vector<long> V_L;
typedef map<long,long> MAP_L_L;
typedef MAP_L_L::iterator MAP_L_L_I;
typedef vector<MAP_L_L> V_MAP_L_L;
typedef multimap<long, long> MMAP_L_L;
typedef MMAP_L_L::iterator MMAP_L_L_I;
typedef map<double,long> MAP_D_L;
typedef MAP_D_L::iterator MAP_D_L_I;
typedef vector<MAP_D_L> V_MAP_D_L;
V_S b;
V_L c; //-- Contagem das ocorrências das palavras, deve ter a mesma dimensão de b
V_MAP_L_L d; //-- Contagem das ocorrências das palavras subseqüentes, deve ter a mesma dimensão de b
MAP_D_L f;
V_MAP_D_L g; //-- Freqüências das ocorrências das palavras subseqüentes, deve ter a mesma dimensão de b
bool ispunctchar (int ch)
{
return ch == '.' || ch == ',' || ch == ':' || ch == ',' || ch == ';' || ch == '!' || ch == '?';
}
bool iswordchar (int ch)
{
//-- Note que todos os caracteres acima de 128 serão considerados alfabéticos
//-- para facilitar.
return 'A' <= ch && ch <= 'Z'
|| 'a' <= ch && ch <= 'z'
|| '0' <= ch && ch <= '9'
|| ch == '_' || ch == '\''
|| ch == '-'
|| ch >= 128;
}
int getword (FILE *v, char word[])
{
int ch;
//-- Devemos pular os caracteres não-alfabéticos [^A-Za-z0-9_']
char *p = word;
while ((ch = getc (v)) != EOF && !iswordchar (ch))
{
if (ispunctchar (ch))
{
*p++ = ch;
*p = '\0';
return ch;
break;
}
}
if (iswordchar (ch))
ungetc (ch, v);
while ((ch = getc (v)) != EOF && iswordchar (ch))
{
*p++ = ch;
}
if (ch != EOF) ungetc (ch, v);
*p = '\0';
return ch; //-- EOF se acabarem as palavras...
}
int main (int argc, char *argv[])
{
char word[1024];
FILE *v, *w;
{
MAP_S_L a;
long code = 0;
long ncodes;
long code1, code2;
fprintf (stderr, "Lendo o arquivo %s\n", argv[1]);
v = fopen (argv[1], "rt");
code2 = 0;
while (getword (v, word) != EOF)
{
//-- Se a palavra não existia antes em A, incrementamos code
if (a.insert(make_pair<string,long>(word, code)).second)
{
code++;
c.resize (c.size() + 1); d.resize(d.size() + 1);
if (code % 1000 == 0)
fprintf (stderr, "\r%d códigos", code);
}
code1 = code2; code2 = a[word];
//-- Contando as palavras
//-- Note que como as palavras agora são códigos, podemos usar um vetor simples
//-- para contar as ocorrências, e um vetor de mapas para contar as ocorrências
//-- da string subseqüentes
c [code1]++;
d [code1][code2]++;
}
ncodes = a.size();
fclose (v);
fprintf (stderr, "\rLidos %d códigos\n", ncodes);
fprintf (stderr, "Invertendo a lista\n");
b.resize (ncodes);
for (MAP_S_L_I p = a.begin(), p_end = a.end(); p != p_end; ++p)
{
//-- p->second contém o código, p->first contém a string
b[p->second] = p->first;
}
//-- c contém as freqüências, mas precisamos ordenar por freqüências relativas
long nTotalWords = 0;
fprintf (stderr, "Determinando as freqüências relativas\n");
{
MMAP_L_L e;
fprintf (stderr, "Passo 1\n");
for (long i = 0; i < c.size(); ++i)
{
nTotalWords += c[i];
e.insert (make_pair<long,long>(c[i], i));
}
fprintf (stderr, "Passo 2\n");
long nAccWords = 0;
for (MMAP_L_L_I p = e.begin(), p_end = e.end(); p != p_end; ++p)
{
nAccWords += p->first;
f[(double)nAccWords / nTotalWords] = p->second;
}
}
//-- Agora para cada palavra subseqüente precisamos determinar a sua freqüência...
fprintf (stderr, "Determinando as freqüências relativas das palavras subseqüentes.\n", ncodes);
for (long i = 0; i < d.size(); ++i)
{
if (i % 200 == 0)
fprintf (stderr, "\r%d palavras...", i);
long nTotalWords = 0;
MMAP_L_L h;
for (MAP_L_L_I p = d[i].begin(), p_end = d[i].end(); p != p_end; ++p)
{
nTotalWords += p->second;
h.insert (make_pair<long,long>(p->second, p->first));
}
MAP_D_L k;
long nAccWords = 0;
for (MMAP_L_L_I p = h.begin(), p_end = h.end(); p != p_end; ++p)
{
nAccWords += p->first;
k[(double)nAccWords/nTotalWords] = p->second;
}
g.push_back (k);
}
fprintf (stderr, "\r%d palavras processadas.\n", d.size());
}
fprintf (stderr, "Gerando as palavras...\n");
w = fopen (argv[2], "wt");
long thisword = 0;
srand (time (NULL));
for (long i = 0; i < 100000; ++i)
{
const char *palavra = b[thisword].c_str();
if (!ispunctchar (palavra[0]))
fprintf (w, " ");
fprintf (w, "%s", palavra);
double r = (double)rand() / RAND_MAX;
MAP_D_L_I p = g[thisword].upper_bound(r);
if (p != g[thisword].end())
{
thisword = p->second;
}
else
{
printf ("!");
thisword = f.upper_bound(r)->second;
}
}
fclose (w);
}
[/code]';
return ch;
break;
}
}
if (iswordchar (ch))
ungetc (ch, v);
while ((ch = getc (v)) != EOF && iswordchar (ch))
{
*p++ = ch;
}
if (ch != EOF) ungetc (ch, v);
*p = '[code]
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <hash_map>
//-- Leia um arquivo texto, e use critérios probabilísticos para gerar um outro texto.
//-- Neste caso iremos verificar para cada palavra qual a probabilidade de ela ser seguida por
//-- uma segunda palavra.
//-- As strings não serão repetidas, mas "internalizadas", ou seja,
//-- apenas uma cópia física de cada string aparecerá na memória. Cada string será representada
//-- por um código.
//-- 1) Ler cada palavra e inseri-la em um mapa A (palavra->codigo). Esse mapa será temporário
//-- porque iremos substituí-lo por um vetor B (código->palavra).
//-- 2) Reler o arquivo, usando o mapa A, palavra->código e procedendo como antes.
//-- 3) Duas strings são iguais se seus códigos forem iguais.
using namespace std;
//
//-- Required by hash_map
//
struct hasher
{
enum { bucket_size = 4, min_buckets = 8 };
/** A seguinte função retorna o hash da string. Adaptada da função de hash do MFC */
size_t operator() (const string& s1) const
{
size_t nHash = 0;
for (string::const_iterator p = s1.begin(), p_end = s1.end(); p != p_end; ++p)
nHash = (nHash<<5) + nHash + *p;
return nHash;
}
/** A seguinte função retorna s1 < s2 */
bool operator() (const string& s1, const string& s2) const
{
return stricmp (s1.c_str(), s2.c_str()) < 0;
}
};
typedef hash_map< string,long,hasher > MAP_S_L;
typedef MAP_S_L::iterator MAP_S_L_I;
typedef vector<string> V_S;
typedef vector<long> V_L;
typedef map<long,long> MAP_L_L;
typedef MAP_L_L::iterator MAP_L_L_I;
typedef vector<MAP_L_L> V_MAP_L_L;
typedef multimap<long, long> MMAP_L_L;
typedef MMAP_L_L::iterator MMAP_L_L_I;
typedef map<double,long> MAP_D_L;
typedef MAP_D_L::iterator MAP_D_L_I;
typedef vector<MAP_D_L> V_MAP_D_L;
V_S b;
V_L c; //-- Contagem das ocorrências das palavras, deve ter a mesma dimensão de b
V_MAP_L_L d; //-- Contagem das ocorrências das palavras subseqüentes, deve ter a mesma dimensão de b
MAP_D_L f;
V_MAP_D_L g; //-- Freqüências das ocorrências das palavras subseqüentes, deve ter a mesma dimensão de b
bool ispunctchar (int ch)
{
return ch == '.' || ch == ',' || ch == ':' || ch == ',' || ch == ';' || ch == '!' || ch == '?';
}
bool iswordchar (int ch)
{
//-- Note que todos os caracteres acima de 128 serão considerados alfabéticos
//-- para facilitar.
return 'A' <= ch && ch <= 'Z'
|| 'a' <= ch && ch <= 'z'
|| '0' <= ch && ch <= '9'
|| ch == '_' || ch == '\''
|| ch == '-'
|| ch >= 128;
}
int getword (FILE *v, char word[])
{
int ch;
//-- Devemos pular os caracteres não-alfabéticos [^A-Za-z0-9_']
char *p = word;
while ((ch = getc (v)) != EOF && !iswordchar (ch))
{
if (ispunctchar (ch))
{
*p++ = ch;
*p = '\0';
return ch;
break;
}
}
if (iswordchar (ch))
ungetc (ch, v);
while ((ch = getc (v)) != EOF && iswordchar (ch))
{
*p++ = ch;
}
if (ch != EOF) ungetc (ch, v);
*p = '\0';
return ch; //-- EOF se acabarem as palavras...
}
int main (int argc, char *argv[])
{
char word[1024];
FILE *v, *w;
{
MAP_S_L a;
long code = 0;
long ncodes;
long code1, code2;
fprintf (stderr, "Lendo o arquivo %s\n", argv[1]);
v = fopen (argv[1], "rt");
code2 = 0;
while (getword (v, word) != EOF)
{
//-- Se a palavra não existia antes em A, incrementamos code
if (a.insert(make_pair<string,long>(word, code)).second)
{
code++;
c.resize (c.size() + 1); d.resize(d.size() + 1);
if (code % 1000 == 0)
fprintf (stderr, "\r%d códigos", code);
}
code1 = code2; code2 = a[word];
//-- Contando as palavras
//-- Note que como as palavras agora são códigos, podemos usar um vetor simples
//-- para contar as ocorrências, e um vetor de mapas para contar as ocorrências
//-- da string subseqüentes
c [code1]++;
d [code1][code2]++;
}
ncodes = a.size();
fclose (v);
fprintf (stderr, "\rLidos %d códigos\n", ncodes);
fprintf (stderr, "Invertendo a lista\n");
b.resize (ncodes);
for (MAP_S_L_I p = a.begin(), p_end = a.end(); p != p_end; ++p)
{
//-- p->second contém o código, p->first contém a string
b[p->second] = p->first;
}
//-- c contém as freqüências, mas precisamos ordenar por freqüências relativas
long nTotalWords = 0;
fprintf (stderr, "Determinando as freqüências relativas\n");
{
MMAP_L_L e;
fprintf (stderr, "Passo 1\n");
for (long i = 0; i < c.size(); ++i)
{
nTotalWords += c[i];
e.insert (make_pair<long,long>(c[i], i));
}
fprintf (stderr, "Passo 2\n");
long nAccWords = 0;
for (MMAP_L_L_I p = e.begin(), p_end = e.end(); p != p_end; ++p)
{
nAccWords += p->first;
f[(double)nAccWords / nTotalWords] = p->second;
}
}
//-- Agora para cada palavra subseqüente precisamos determinar a sua freqüência...
fprintf (stderr, "Determinando as freqüências relativas das palavras subseqüentes.\n", ncodes);
for (long i = 0; i < d.size(); ++i)
{
if (i % 200 == 0)
fprintf (stderr, "\r%d palavras...", i);
long nTotalWords = 0;
MMAP_L_L h;
for (MAP_L_L_I p = d[i].begin(), p_end = d[i].end(); p != p_end; ++p)
{
nTotalWords += p->second;
h.insert (make_pair<long,long>(p->second, p->first));
}
MAP_D_L k;
long nAccWords = 0;
for (MMAP_L_L_I p = h.begin(), p_end = h.end(); p != p_end; ++p)
{
nAccWords += p->first;
k[(double)nAccWords/nTotalWords] = p->second;
}
g.push_back (k);
}
fprintf (stderr, "\r%d palavras processadas.\n", d.size());
}
fprintf (stderr, "Gerando as palavras...\n");
w = fopen (argv[2], "wt");
long thisword = 0;
srand (time (NULL));
for (long i = 0; i < 100000; ++i)
{
const char *palavra = b[thisword].c_str();
if (!ispunctchar (palavra[0]))
fprintf (w, " ");
fprintf (w, "%s", palavra);
double r = (double)rand() / RAND_MAX;
MAP_D_L_I p = g[thisword].upper_bound(r);
if (p != g[thisword].end())
{
thisword = p->second;
}
else
{
printf ("!");
thisword = f.upper_bound(r)->second;
}
}
fclose (w);
}
[/code]';
return ch; //-- EOF se acabarem as palavras...
}
int main (int argc, char *argv[])
{
char word[1024];
FILE *v, *w;
{
MAP_S_L a;
long code = 0;
long ncodes;
long code1, code2;
fprintf (stderr, "Lendo o arquivo %s\n", argv[1]);
v = fopen (argv[1], "rt");
code2 = 0;
while (getword (v, word) != EOF)
{
//-- Se a palavra não existia antes em A, incrementamos code
if (a.insert(make_pair<string,long>(word, code)).second)
{
code++;
c.resize (c.size() + 1); d.resize(d.size() + 1);
if (code % 1000 == 0)
fprintf (stderr, "\r%d códigos", code);
}
code1 = code2; code2 = a[word];
//-- Contando as palavras
//-- Note que como as palavras agora são códigos, podemos usar um vetor simples
//-- para contar as ocorrências, e um vetor de mapas para contar as ocorrências
//-- da string subseqüentes
c [code1]++;
d [code1][code2]++;
}
ncodes = a.size();
fclose (v);
fprintf (stderr, "\rLidos %d códigos\n", ncodes);
fprintf (stderr, "Invertendo a lista\n");
b.resize (ncodes);
for (MAP_S_L_I p = a.begin(), p_end = a.end(); p != p_end; ++p)
{
//-- p->second contém o código, p->first contém a string
b[p->second] = p->first;
}
//-- c contém as freqüências, mas precisamos ordenar por freqüências relativas
long nTotalWords = 0;
fprintf (stderr, "Determinando as freqüências relativas\n");
{
MMAP_L_L e;
fprintf (stderr, "Passo 1\n");
for (long i = 0; i < c.size(); ++i)
{
nTotalWords += c[i];
e.insert (make_pair<long,long>(c[i], i));
}
fprintf (stderr, "Passo 2\n");
long nAccWords = 0;
for (MMAP_L_L_I p = e.begin(), p_end = e.end(); p != p_end; ++p)
{
nAccWords += p->first;
f[(double)nAccWords / nTotalWords] = p->second;
}
}
//-- Agora para cada palavra subseqüente precisamos determinar a sua freqüência...
fprintf (stderr, "Determinando as freqüências relativas das palavras subseqüentes.\n", ncodes);
for (long i = 0; i < d.size(); ++i)
{
if (i % 200 == 0)
fprintf (stderr, "\r%d palavras...", i);
long nTotalWords = 0;
MMAP_L_L h;
for (MAP_L_L_I p = d[i].begin(), p_end = d[i].end(); p != p_end; ++p)
{
nTotalWords += p->second;
h.insert (make_pair<long,long>(p->second, p->first));
}
MAP_D_L k;
long nAccWords = 0;
for (MMAP_L_L_I p = h.begin(), p_end = h.end(); p != p_end; ++p)
{
nAccWords += p->first;
k[(double)nAccWords/nTotalWords] = p->second;
}
g.push_back (k);
}
fprintf (stderr, "\r%d palavras processadas.\n", d.size());
}
fprintf (stderr, "Gerando as palavras...\n");
w = fopen (argv[2], "wt");
long thisword = 0;
srand (time (NULL));
for (long i = 0; i < 100000; ++i)
{
const char *palavra = b[thisword].c_str();
if (!ispunctchar (palavra[0]))
fprintf (w, " ");
fprintf (w, "%s", palavra);
double r = (double)rand() / RAND_MAX;
MAP_D_L_I p = g[thisword].upper_bound(r);
if (p != g[thisword].end())
{
thisword = p->second;
}
else
{
printf ("!");
thisword = f.upper_bound(r)->second;
}
}
fclose (w);
}