como hacer un generador??

Iniciado por jaime.urizar, 11 Julio 2012, 08:34 AM

0 Miembros y 1 Visitante están viendo este tema.

xiruko

#40
me gustaria a mi tambien compartir el codigo que he hecho, seguramente para nada sea el mas eficiente pero me gustaria saber como podria optimizarlo. genera la combinacion de AAAAA00000 a ZZZZZ99999 (no en el orden tipico).

#include <stdio.h>

#define NUM 5 //numero de letras

void cambiar_letras(char* letras, int* pos);

int main(int argc, char** argv)
{
FILE *fd;
char letras[]="AAAAA";
int posLet=0, i;

fd=fopen("diccionario.txt", "w");

while (posLet < NUM)
{
for (i=0; i<100000; i++)
fprintf(fd, "%s%.5d\n", letras, i);

cambiar_letras(letras, &posLet);
}

fclose(fd);
return 0;
}

void cambiar_letras(char* letras, int* pos)
{
int i;

for (i=0; i<=*pos && *pos<=NUM; i++)
{
if (letras[i] < 'Z') {
(letras[i])++;
break;
} else {
letras[i]='A';
if ( i==*pos && (letras[i+1]=='A' || letras[i+1]=='\0') )
(*pos)++;
}
}
}


pd. gracias DickGumshoe por el especificador de formato %.5d en los enteros, no tenia ni idea de que podia representarse el 1 como 00001.

BlackZeroX

#41
.
The Dark Shadow is my passion.

DickGumshoe

Cita de: BlackZeroX (Astaroth) en 13 Julio 2012, 15:44 PM
La problemática de almacenamiento es despreciable... lee bien lo que se quiere.

Dulces Lunas!¡.

Pero después nos pide cómo almacenarlo en un .txt... y por tanto es imposible (o eso creo xD).

Por cierto, estoy volviendo a hacer una modificación de mi código que he encontrado un error...

Saludos!

BlackZeroX

si tienes un error cambia tu limite del for y veras...

* No es imposible, solo se tendrían que usar varios HDD y a su vez varios archivos...

Dulces Lunas!¡.
The Dark Shadow is my passion.

DickGumshoe

Cita de: BlackZeroX (Astaroth) en 13 Julio 2012, 15:54 PM
si tienes un error cambia tu limite del for y veras...

Dulces Lunas!¡.

No me refería a eso... El límite del for lo tengo puesto así porque el programa es para generar hasta 99999. Claro que si cambio el límite y pongo más saldrá mal, pero porque pongo %.5d, no por otra cosa...

Sí, eso de usar varios archivos es una buena idea!

Saludos!

BlackZeroX

Yo te decía que cambiaras el limite para que vieras tu error...

Dulces Lunas!¡.
The Dark Shadow is my passion.

DickGumshoe

#46
He cambiado el código arreglando errores:

#include <stdio.h>

FILE *fp;

void numeros(char *Letras, int n)
{
int i;
for(i=0;i<100000;i++)
{
    printf("%s%.5d\n",Letras, i);
    fprintf(fp, "%s%.5d\n", Letras, i);
}
}

void Generador(char *Letras, int n)
{
   int count, resta=1, llamada;
   while(llamada != 5)
   {
       numeros(Letras, n);
       count = n;
       Letras[n]++;
       llamada = 0;
       while(count >= 0)
       {
           if(Letras[count] > 90)
           {
               Letras[count] = 65;
               Letras[count-1]++;
               llamada++;
           }
           count--;
           resta++;
       }
   }
}
int main()
{
   char Letras[] = "AAAAA";
   fp = fopen("combinacion.txt", "w");
   Generador(Letras, 4);
   fclose(fp);
   return 0;
}


¿Te referías a ese error?

Saludos.


BlackZeroX

#47
.
En efecto ese era el error... y como no me quiero quedar atras con los numeros aqui lo dejo ya completo:

Código (cpp) [Seleccionar]


#include <iostream>
#include <iomanip>
#include <cmath>

using namespace std;

inline string &addWord(string &text) {
   string::reverse_iterator it = text.rbegin();
   for (; it != text.rend(); it++) {
       ++(*it);
       if (tolower(*it) >= 'a' && tolower(*it) <= 'z') break;
       (*it) = (islower(*it))? 'a': 'A';
   }
   return text;
}

size_t addAllWord(string text, void (*callback)(string&, bool&) = NULL) {
   bool cancel = false;
   register size_t i = 0, lim = pow(26, text.size());
   if (!callback) return lim;
   for (;(i < lim) && (cancel ==false); i++) {
       callback(addWord(text), cancel);
   }
   return i;
}

void showWords(string& text, bool& cancel) {
   for (register int i = 0; i <= 9999; i++) {
       cout << text << setw(4) << setfill('0') << i << endl;
   }
}

int main() {
   string text = "ZZZx";
   cout << addAllWord(text, showWords) << endl;
   cin.get();
   return 0;
}



Dulces Lunas!¡.
The Dark Shadow is my passion.

DickGumshoe

#48
Bueno, entonces ya tenemos varios códigos que generan lo que se pedía en el tema  :D

BlackZeroX (Astaroth), con lo de imposible en un ordenador normal me refería a uno cualquiera, sin discos duros extras ni nada...

Saludos y gracias por avisar del error!

EDITO:

Bueno, creo que ya, a no ser que el autor del tema diga lo contrario, su duda ya está solucionada.

dato000

Voy a dejar un post resumen de este tema, muy interesante, queria dejar el mio pero no es tan bueno jaajaj sigo mirando varias cosas. Es practicamente uno que DickGumshoe deja pero trate de corregir la recursividad pero no me funciono muy bien, en fin, dejo las soluciones publicadas.

muy buen post realmente muy bueno


Aqui el primero de DickGumshoe


#include <stdio.h>

FILE *fp;

void numeros(char *Letras, int n)
{
int i;
for(i=0;i<100000;i++)
{
    printf("%s%.5d\n",Letras, i);
    fprintf(fp, "%s%.5d\n", Letras, i);
}
}

void Generador(char *Letras, int n)
{
   int count, resta=1, llamada;
   while(llamada != 5)
   {
       numeros(Letras, n);
       count = n;
       Letras[n]++;
       llamada = 0;
       while(count >= 0)
       {
           if(Letras[count] > 90)
           {
               Letras[count] = 65;
               Letras[count-1]++;
               llamada++;
           }
           count--;
           resta++;
       }
   }
}
int main()
{
   char Letras[] = "AAAAA";
   fp = fopen("combinacion.txt", "w");
   Generador(Letras, 4);
   fclose(fp);
   return 0;
}



Otra solución aportada por BlackZeroX

Código (cpp) [Seleccionar]


#include <iostream>
#include <iomanip>
#include <cmath>

using namespace std;

inline string &addWord(string &text) {
   string::reverse_iterator it = text.rbegin();
   for (; it != text.rend(); it++) {
       ++(*it);
       if (tolower(*it) >= 'a' && tolower(*it) <= 'z') break;
       (*it) = (islower(*it))? 'a': 'A';
   }
   return text;
}

size_t addAllWord(string text, void (*callback)(string&, bool&) = NULL) {
   bool cancel = false;
   register size_t i = 0, lim = pow(26, text.size());
   if (!callback) return lim;
   for (;(i < lim) && (cancel ==false); i++) {
       callback(addWord(text), cancel);
   }
   return i;
}

void showWords(string& text, bool& cancel) {
   for (register int i = 0; i <= 9999; i++) {
       cout << text << setw(4) << setfill('0') << i << endl;
   }
}

int main() {
   string text = "ZZZx";
   cout << addAllWord(text, showWords) << endl;
   cin.get();
   return 0;
}






Y otra alternativa aportada por xiruko

#include <stdio.h>

#define NUM 5 //numero de letras

void cambiar_letras(char* letras, int* pos);

int main(int argc, char** argv)
{
FILE *fd;
char letras[]="AAAAA";
int posLet=0, i;

fd=fopen("diccionario.txt", "w");

while (posLet < NUM)
{
for (i=0; i<100000; i++)
fprintf(fd, "%s%.5d\n", letras, i);

cambiar_letras(letras, &posLet);
}

fclose(fd);
return 0;
}

void cambiar_letras(char* letras, int* pos)
{
int i;

for (i=0; i<=*pos && *pos<=NUM; i++)
{
if (letras[i] < 'Z') {
(letras[i])++;
break;
} else {
letras[i]='A';
if ( i==*pos && (letras[i+1]=='A' || letras[i+1]=='\0') )
(*pos)++;
}
}
}


EXCELENTES SOLUCIONES, REALMENTE ESTAN A OTRO NIVEL.