como hacer un generador??

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

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

jaime.urizar

hola amigos

les pido ayuda con algo que vi desde hace mucho, es como realizar un generador que muestre como resultado:

AAAAA
AAAAB
AAAAC
.........
.........
ZZZZZ

y algo mucho mas desafiante que no pude ni encontrar partes en internet y bueno mi conocimiento no es tan amplio pero decearia aprender a poder generar un..


AAAAA00000
AAAAA00001
AAAAA00002
....
....
....
AAAAB00000
AAAAB00001
....
.....
ZZZZZ99999

solo pude sacar cuantos resultados tendre :-( (son 14348907000000 posibles combinaciones)


una ayudita porfavor enserio me mata la curiosidad de aprender a hacer un contador o generador de ese tipo, y gracias de antemano por todo

DickGumshoe

Al ver este tema, me ha parecido interesante y he creado uno del primer tipo que pides (solo con letras).

Por ahora solo tiene todas las posibles combinaciones de cinco caracteres comprendidos entre la 'A' a 'Z'. Después lo mejoraré para que acepte números y para que sea de n caracteres. Eso sí, creo que el programa no es muy eficiente, así que también tengo que corregir este punto.

#include <stdio.h>

void PrimeraLetra(char *Letras, int n)
{
    printf("%s\n", Letras);
    Letras[n]++;
    if(Letras[n] <= 90) PrimeraLetra(Letras, n);
    else Letras[n] = 65;
}

void SegundaLetra(char *Letras, int n)
{
    PrimeraLetra(Letras, n);
    Letras[n-1]++;
    if(Letras[n-1] <= 90) SegundaLetra(Letras, n);
    else Letras[n-1] = 65;
}

void TerceraLetra(char *Letras, int n)
{
    SegundaLetra(Letras, n);
    Letras[n-2]++;
    if(Letras[n-2] <= 90) TerceraLetra(Letras, n);
    else Letras[n-2] = 65;
}

void CuartaLetra(char *Letras, int n)
{
    TerceraLetra(Letras, n);
    Letras[n-3]++;
    if(Letras[n-3] <= 90) CuartaLetra(Letras, n);
    else  Letras[n-3] = 65;
}

void QuintaLetra(char *Letras, int n)
{
    CuartaLetra(Letras, n);
    Letras[n-4]++;
    if(Letras[n-4] <= 90) QuintaLetra(Letras, n);
    else Letras[n-4] = 65;
}

int main()
{
    char Letras[] = "AAAAA";
    QuintaLetra(Letras, 4);
    return 0;
}


Si tienes alguna duda pregunta  :D

Saludos.

SXF

Una pregunta 90 y 65 que indican?¿

DickGumshoe

Cita de: SXF en 11 Julio 2012, 18:16 PM
Una pregunta 90 y 65 que indican?¿

Se me olvidó poner un comentario para explicarlo. 65 es el valor ASCII del carácter 'A', y 90 el del carácter 'Z'.

Sé que también se podría poner así:

if(Letras[n] <= 'Z') PrimeraLetra(Letras, n);

Pero he cogido la costumbre de poner el valor en ASCII.

jaime.urizar

Gracias SXF es muy bueno, para agregar los números sería un buen desafío ya que tendríamos que unificar todo el método "LETRA X Número" gracias de nuevo SXF me daba curiosidad saber como genera ese tipo de código, dime algo más vi en algunos códigos que guardan lo que imprimen en pantalla con una extensión ".txt" como hacen eso???

DickGumshoe

He editado mi código para que puedas poner todo en un archivo. Aquí te lo dejo:

#include <stdio.h>

FILE *fp;

void PrimeraLetra(char *Letras, int n)
{
    printf("%s\n", Letras); //Imprimimos
    fputs(Letras, fp);
    fputc('\n', fp);
    Letras[n]++; //Pasamos al siguiente carácter [al siguiente valor ASCII]
    if(Letras[n] <= 90) PrimeraLetra(Letras, n); /*90 es el valor ASCII de  'Z'. Si no se ha superado
                                                                                  ese valor, significa que el nuevo carácter está
                                                                                  comprendido entre la 'A' y la 'Z', y, por tanto, es
                                                                                  un carácter de los que queremos generar. Así, llamamos
                                                                                  a la función de nuevo.*/
    else Letras[n] = 65;
}

void SegundaLetra(char *Letras, int n) //Algo similar a la función anterior.
{
    PrimeraLetra(Letras, n);
    Letras[n-1]++;
    if(Letras[n-1] <= 90) SegundaLetra(Letras, n);
    else Letras[n-1] = 65;
}

void TerceraLetra(char *Letras, int n)
{
    SegundaLetra(Letras, n);
    Letras[n-2]++;
    if(Letras[n-2] <= 90) TerceraLetra(Letras, n);
    else Letras[n-2] = 65;
}

void CuartaLetra(char *Letras, int n)
{
    TerceraLetra(Letras, n);
    Letras[n-3]++;
    if(Letras[n-3] <= 90) CuartaLetra(Letras, n);
    else  Letras[n-3] = 65;
}

void QuintaLetra(char *Letras, int n)
{
    CuartaLetra(Letras, n);
    Letras[n-4]++;
    if(Letras[n-4] <= 90) QuintaLetra(Letras, n);
    else Letras[n-4] = 65;
}

int main()
{
    char Letras[] = "AAAAA";
    fp = fopen("combinacion.txt", "w");
    QuintaLetra(Letras, 4);
    fclose(fp);
    return 0;
}


Las funciones que he utilizado, para que veas cómo lo he hecho, son:

fopen, fclose, fputc, fputs

Cuando vaya editando el código iré poniéndolo, a ver si después lo hago más eficiente y además meto los números.

Saludos.

DickGumshoe

He terminado el código para que muestre todas las combinaciones posibles desde AAAAA00000 hasta ZZZZZ99999.

El algoritmo está bien, sin embargo, es tan ineficiente que a mitad del programa me sale un mensaje que dice "Generador.exe dejó de funcionar. Windows está buscando una solución al problema", pulso en aceptar y se cierra el programa...

#include <stdio.h>

FILE *fp;

void numeros(char *Letras, int n)
{
    printf("%s\n", Letras); //Imprimimos
    fputs(Letras, fp);
    fputc('\n', fp);

    Letras[n+5]++;

    if(Letras[n+2] > 57)
    {
        Letras[n+2] = 48;
        Letras[n+1]++;
    }
    else if(Letras[n+3] > 57)
    {
        Letras[n+3] = 48;
        Letras[n+2]++;
    }
    else if (Letras[n+4] > 57)
    {
        Letras[n+4] = 48;
        Letras[n+3]++;
    }
    else if(Letras[n+5] > 57)
    {
        Letras[n+5] = 48;
        Letras[n+4]++;
    }
    if(Letras[n+1] <= 57) numeros(Letras, n);

}

void PrimeraLetra(char *Letras, int n)
{

    numeros(Letras, n);
    Letras[n]++; //Pasamos al siguiente carácter [al siguiente valor ASCII]
    if(Letras[n] <= 90) PrimeraLetra(Letras, n); /*90 es el valor ASCII de  'Z'. Si no se ha superado
                                                                                  ese valor, significa que el nuevo carácter está
                                                                                  comprendido entre la 'A' y la 'Z', y, por tanto, es
                                                                                  un carácter de los que queremos generar. Así, llamamos
                                                                                  a la función de nuevo.*/
    else Letras[n] = 65;
}

void SegundaLetra(char *Letras, int n) //Algo similar a la función anterior.
{
    PrimeraLetra(Letras, n);
    Letras[n-1]++;
    if(Letras[n-1] <= 90) SegundaLetra(Letras, n);
    else Letras[n-1] = 65;
}

void TerceraLetra(char *Letras, int n)
{
    SegundaLetra(Letras, n);
    Letras[n-2]++;
    if(Letras[n-2] <= 90) TerceraLetra(Letras, n);
    else Letras[n-2] = 65;
}

void CuartaLetra(char *Letras, int n)
{
    TerceraLetra(Letras, n);
    Letras[n-3]++;
    if(Letras[n-3] <= 90) CuartaLetra(Letras, n);
    else  Letras[n-3] = 65;
}

void QuintaLetra(char *Letras, int n)
{
    CuartaLetra(Letras, n);
    Letras[n-4]++;
    if(Letras[n-4] <= 90) QuintaLetra(Letras, n);
    else Letras[n-4] = 65;
}

int main()
{
    char Letras[] = "AAAAA00000";
    fp = fopen("combinacion.txt", "w");
    QuintaLetra(Letras, 4);

    fclose(fp);
    return 0;
}


Me parece a mí que la dificultad de este problema está más en la eficiencia... Al menos tenemos ya para que nos haga desde AAAAA hasta ZZZZZ...

Saludos!

jaime.urizar

#7
muchas gracias DickGumshoe lo estoy probando, mira yo encontre este codigo dame tu opinion de que tal esta:

{
char a,b,c,d,e,n1,n2,n3,n4,n5;

 for(a = 'A'; a<= 'Z'; a++)
  for(b = 'A'; b <= 'Z'; b++)
   for(c = 'A'; c <= 'Z'; c++)
    for(d = 'A'; d <= 'Z'; d++)
     for(e = 'A'; e <= 'Z'; e++)
      for(n1 = 0; n1 < 10; n1++)
       for(n2 = 0; n2 < 10; n2++)
        for(n3 = 0; n3 < 10; n3++)
         for(n4 = 0; n4 < 10; n4++)
          for(n5 = 0; n5 < 10; n5++)
            printf("%c%c%c%c%c%d%d%d%d%d\n",a,b,c,d,e,n1,n2,n3,n4,n5);
}



y una ultima pregunta como se utiliza para guardar lo que se imprime en pantalla en un ".txt"

probando tu codigo me di cuenta que imprime de esta manera:

AAAAIW:0232
AAAAIX:0233
AAAAIY:0234
AAAAIZ:0235


deberia de imprimir

AAAAIW00232
AAAAIW00233
AAAAIW00234
AAAAIW00235
AAAAIW00236
AAAAIW00237

se salta muchas combinaciones existentes
muchas gracias

DickGumshoe

Ese código debe salir también, pero yo hice el programa a mi manera porque me pareció muy típico eso de hacer tantos for anidados, y me gustó hacerlo de otra forma, con recursividad.

Eso sí, en ese código las variables n1, n2, n3, n4 y n5 son char, no debes imprimirlas como %d, y en el bucle for no es desde 0 hasta 9, sino que tienes que hacer desde 48 hasta 57 (valor ASCII de 0 y 9, respectivamente).

Para imprimirlo en un .txt tienes que declarar una variable así:

FILE *nombre_variable;

Entonces, para editar el .txt, eliges un nombre y el modo en que lo vas a abrir:

nombre_variable = fopen ("nombre_archivo.txt", "w");

En este caso es un .txt, pero también puedes poner .dat o la extensión que quieras. El modo en que abrimos el archivo es "w", (write, escritura). Pero hay muchos más. Para conocerlos, puedes ver el enlace que te pasé en un mensaje anterior con la función fopen() explicada.

Ya usas la función fputs() para poner una cadena en el fichero (también te pasé el enlace a cómo usarla).

Y para cerrar el fichero, poner:

fclose(nombre_variable);

A ver si conseguimos que nos salga (aunque el algoritmo mío está bien, pero no llega a terminar, no sé por qué, a ver si alguien me puede comentar por qué...)

Saludos!

jaime.urizar

probando tu codigo me di cuenta que imprime de esta manera:

AAAAIW:0232
AAAAIX:0233
AAAAIY:0234
AAAAIZ:0235


deberia de imprimir

AAAAIW00232
AAAAIW00233
AAAAIW00234
AAAAIW00235
AAAAIW00236
AAAAIW00237

se salta muchas combinaciones existentes ademas no genera el .txt
muchas gracias