¿Algoritmo existente?

Iniciado por goto C, 28 Julio 2013, 13:54 PM

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

goto C

Hola, este es mi primer mensajito jeje, me he visto obligado a pedir ayuda, al principio me veía capaz, pero después de probar mil códigos diferentes y ver que siempre todos fallan en algún punto acudo para pedir que me echéis una mano, plissss.

El caso, tengo un array (correctamente inicalizado y comprobado que contiene bien los caracteres y todo ok), así, suponiendo que contiene los caracteres; a b c d, el programa debe hacer las siguientes combinaciones:

ab
ac
ad
bc
bd
cd
abc
abd
bcd
abcd

Nota: si se conoce el número de caracteres es relativamente sencillo, pero se trata de hacer combinaciones del modo que explico sin saber el número de caracteres, es decir, el usuario introduce por teclado el número, y a continuación los caracteres, pero el código del programa debe estar preparado para funcionar sea cual sea el número, si no me explico me lo decís jeje.

No importa el orden, únicamente importa que estén todas las combinaciones. Me extraña que no haya ningún algoritmo ya desarrollado que haga esto, ¿no tiene ningún nombre realizar combinaciones de esta manera?, pregunto par poder googlear jeje.
Bueno, si a alguien se le ocurre cómo hacerlo, aunque sea la idea, no es necesario que me de el código, se lo agradezco mucho. El programa es en C, aunque si alguno sabe hacerlo en otro lenguaje que lo haga en ese y ya lo "traduciremos" jeje.

Muchísimas gracias. Saludos.

Stakewinner00

Si quieres que haga todas las combinaciones de unos caracteres puede buscar por fuerza bruta.
Lo del numero a que te refieres?

amchacon

Yo ya lo tengo hecho y realizado:

Recursivo:


const char Diccionario[]= {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
'p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J'
,'K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3',
'4','5','6','7','8','9','\0'};

const int Tamanyo_Diccionario;

//...

Tamanyo_Diccionario = strlen(Diccionario);

// Llamamos a la funcion

while(!explora(intento,password,0,hasta)) { hasta++;
    intento[hasta] = '\0';}

printf("La contrasenaya es: %s",intento);

//...

char explora (char* Password,const char* Correcta, int desde, int hasta){
  if (desde==hasta){
    return !strcmp(Password,Correcta);
  }else{
    int i = 0;
    for (i=0; i< TamanyoDiccionario; i++){
      Password [desde] = Diccionario[i];
       if (explora (Password, Correcta, desde+1, hasta))
        return 1;
    }
  }
  return 0;
}


Otra modalidad iterativa (lo usé para resolver sudokus y está en C++, tendrás que adaptarlo):

Código (cpp) [Seleccionar]
bool Resolver(short Tablero[MAX][MAX])
{
    vector<pair<int,int> > Casillas;
    for (short j = 0; j < MAX;j++)
        for (short i = 0; i < MAX;i++)
            if (Tablero[i][j] == 0)
                Casillas.push_back(make_pair(i,j));

    register short Inicio = Casillas.size()-1;

    short Actual;
    short i;

    for (i = 0; i < Casillas.size();i++)
    {
            Tablero[Casillas[i].first][Casillas[i].second] = i%(MAX)+1;
    }

   // Ultimo_Movimiento = 1;

    while(true)
    {
        for (i = 1; i < MAX;i++)
        {

            Tablero[Casillas[Inicio].first][Casillas[Inicio].second] = i;

            if (Resuelto(Tablero))
                return true;
        }

        Tablero[Casillas[Inicio].first][Casillas[Inicio].second] = 1;

        if (Inicio == 0)
                Inicio++;
        else
        {
            Actual = Inicio-1;

            Tablero[Casillas[Actual].first][Casillas[Actual].second] ++;

            while (Tablero[Casillas[Actual].first][Casillas[Actual].second] > (MAX))
            {
               Tablero[Casillas[Actual].first][Casillas[Actual].second] = 1;

                Actual--;

                if (Actual == -1)
                {
                    return false;
                }
                Tablero[Casillas[Actual].first][Casillas[Actual].second]++;

            }

        }

    }

}

Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

goto C

#3
Gracias a los dos, muchas gracias. Amchacon, te he enviado un mensaje con unos problemillas que tengo con tu programa, si no te importa, cuando tengas tiempo échale un vistacillo que estoy muy perdido jejeje.

Stakewinner00 lo que estoy tratando de hacer es un generador de fuerza bruta, lo que sucede es que ya tengo todas las partes principales del programa funcionando, solamente me falta ésta que os comento, lo cual no es fuerza bruta, pues son solamente algunas combinaciones de todas las posibles con esos caracteres. Aunque si alguno sabe de alguna manera (directamente, sin varias partes de código) de hacer todas las combinaciones posibles (fuerza bruta) de otra manera que lo diga porfa jejeje, que me adapto.

Con lo del número me refiero a que pueden ser 3 caracteres o 15, es decir, lo único en común es la manera de hacer las combinaciones, que es como explico en el ejemplo.

Saludos y gracias. :rolleyes:

goto C

Amchacon, he estado mirando tu programa, el que está en C, no el de C++, y me da errores de compilación, ¿qué compilador usas?

Además agradecería que alguien me explicara un poco el código, porque no entiendo bien el funcionamiento ni cómo está estructurado.

Saludos, gracias.

Stakewinner00

Cita de: goto C en 28 Julio 2013, 21:02 PM
Amchacon, he estado mirando tu programa, el que está en C, no el de C++, y me da errores de compilación, ¿qué compilador usas?

Además agradecería que alguien me explicara un poco el código, porque no entiendo bien el funcionamiento ni cómo está estructurado.

Saludos, gracias.

El código falta aplicarlo. Tienes que poner los includes necesarios, el main, etc.

goto C

Ya hombre, eso ya está hecho, además me lo mandó amchacon completo, pero ni con esas compila...

Stakewinner00

Cita de: goto C en 28 Julio 2013, 21:46 PM
Ya hombre, eso ya está hecho, además me lo mandó amchacon completo, pero ni con esas compila...
Postea aquí el código entero y te intentamos ayudar

goto C

#include <stdio.h>
#include <string.h>

const char Diccionario_Default[]= {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
'p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J'
,'K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3',
'4','5','6','7','8','9','\0'};

const char Diccionario_Mayusculasoff[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
'p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','\0'};

const char Diccionario_Minusculasoff[] = {'A','B','C','D','E','F','G','H','I','J'
,'K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3',
'4','5','6','7','8','9','\0'};

const char Diccionaro_Numerosoff[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
'p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J'
,'K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\0'};

const char Diccionario_MayusculasNumerosoff[]= {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
'p','q','r','s','t','u','v','w','x','y','z','\0'};

const char Diccionario_MinusculasNumerosoff[]= {'A','B','C','D','E','F','G','H','I','J'
,'K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\0'};

const char Diccionario_MayusculasMinusculasoff[]= {'0','1','2','3','4','5','6','7','8','9','\0'};

char* Diccionario = Diccionario_Default;
int TamanyoDiccionario = 0;
char explora (char* Password,const char* Correcta, int desde, int hasta);

int main()
{
    char LongitudMin;
    char Opcion;
    char password[256];
    char intento[256] = "as";
    //char* valor = fgets(password,255,stdin);

    TamanyoDiccionario = strlen(Diccionario);
    puts("Introduce tu contrasenya: ");

    scanf("%s",password);

    puts("Quieres proporcionar opciones adicionales? (s/n): ");
    scanf(" %c",&Opcion);

    if (Opcion == 's' || Opcion == 'S')
    {
         char Mayuscula;
        char Minuscula;
        char Numeros;
        puts("Que longitud tiene al menos contrasenya? ");
        scanf("%d",&LongitudMin);

        if (LongitudMin < 0)
            LongitudMin = 0;

        puts("Tiene letras mayusculas? (S/N) ");
        scanf(" %c",&Mayuscula);

        puts("Tiene letras minusculas? (S/N)");
        scanf(" %c",&Minuscula);

        puts("Tiene numeros? (S/N)");
        scanf(" %c",&Numeros);

        #define Afr(tipo) (tipo == 's' || tipo == 'S')

        if (!Afr(Mayuscula) && !Afr(Minuscula) && Afr(Numeros)) // 001
            Diccionario = Diccionario_MayusculasMinusculasoff;

        if (!Afr(Mayuscula) && Afr(Minuscula) && !Afr(Numeros)) // 010
            Diccionario = Diccionario_MayusculasNumerosoff;

        if (!Afr(Mayuscula) && Afr(Minuscula) && Afr(Numeros)) // 011
            Diccionario = Diccionario_Mayusculasoff;

        if (Afr(Mayuscula) && !Afr(Minuscula) && !Afr(Numeros)) // 100
            Diccionario = Diccionario_MinusculasNumerosoff;

        if (Afr(Mayuscula) && !Afr(Minuscula) && Afr(Numeros)) // 101
            Diccionario = Diccionario_Minusculasoff;

        if (Afr(Mayuscula) && Afr(Minuscula) && !Afr(Numeros)) // 110
            Diccionario = Diccionaro_Numerosoff;

        if (Afr(Mayuscula) && Afr(Minuscula) && Afr(Numeros)) // 111
            Diccionario = Diccionario_Default;

        TamanyoDiccionario = strlen(Diccionario);// Generar Diccionario

    }
    else
        {
            LongitudMin = 0;
        }

    int hasta = LongitudMin;

    while(!explora(intento,password,0,hasta)) { hasta++;
    intento[hasta] = '\0';}

    printf("La contrasena es %s",intento);

    return 0;
}

char explora (char* Password,const char* Correcta, int desde, int hasta){
  if (desde==hasta){
    return !strcmp(Password,Correcta);
  }else{
    int i = 0;
    for (i=0; i< TamanyoDiccionario; i++){
      Password [desde] = Diccionario[i];
       if (explora (Password, Correcta, desde+1, hasta))
        return 1;
    }
  }
  return 0;
}

Stakewinner00

#9
Pues ami si que me compila todo y que me da alertas podrías poner lo que te pone ati?
Citara.c:80:25: warning: assignment discards 'const' qualifier from pointer target ty
pe [enabled by default]
Ahora miro por que se trata, ya editare si eso.

EDITO: El error ocurre por que lo declaras como const

No estaría mejor declarar un array con todas las posibilidades y luego estableces las que el usuario elija?