Fundamentos:Solucións:Cálculo de Permutacións
De ASIRodeira
Escribir un programa que permita visualizar todas as permutacións dos elementos dunha taboa de caracteres suministrada la liña de comandos.
Índice |
Solución de Xavi:
Versión 1
Esta implementación é recursiva e consiste en ir intercambiando o primeiro elemento da cadea e facendo as permutacións da cadea restante.
Pseudocódigo
Partimos da cadea 'orixinal', na que iremos intercambiando o primeiro elemento e aplicando a permutación recursiva a 'cadea' restante:
Si a Lonxitude da cadea a permutar é 1, visualizar a cadea orixinal
Se Non
permuta a cadea a partir de cadea[1]
i=0
Mentras que i< lonxitude da cadea a permutar - 1
intercambia o elemento 0 da cadea co elemento i+1
permuta a cadea a partir de cadea[1]
intercambia o elemento 0 da cadea co elemento i+1, (para ter de novo a cadea anterior á permutación)
i++;
Fin-Mentras
Fin-Se
Implementación en C
#include <stdio.h> #include <string.h> /* cambio * Recibe: * A cadea (c), e a posición do elemento a intercambiar co primeiro (i) * Descripción: * Intercambia c[0] con c[i] */ void cambio(char *c,int i) { char t; t=c[0]; c[0]=c[i]; c[i]=t; } /* permuta * Recibe: * A dirección da cadea orixinal (orix), para visualizar o resultado de cada permutación * A dirección da cadea a permutar (cad) * Descripción: * Visualiza as distintas permutacións de cad. Como utiliza a recursión se precisa * o principio da cadea orixinal para visualizar a secuencia completa. */ void permuta(char *orix,char *cad) { int lon; int i; lon=strlen(cad); if (lon==1) printf("%s\n",orix); else { permuta(orix,&cad[1]); // Permutamos a cadea restante (o primeiro elemento é o orixinal) for(i=0;i<lon-1;i++) { cambio(cad,i+1); // Intercambiamos o primeiro elemento permuta(orix,&cad[1]); // Permutamos a cadea restante cambio(cad,i+1); // Desfacemos o intercambio } } } /* Principal * */ int main(int argc,char *argv[]) { int c; char buffer[256]; if (argc!=2) printf("USO: permuta cadenadeelementos\n"); else { permuta(argv[1],argv[1]); } return 0; }
Implementación en Java
Versión 2
Esta implementación baséase no cálculo dunha permutación concreta baseada nunha serie ordeada de permutacións. Para visualizalas todas bastará visualizar as n! permutacións, sendo n o número de elementos da cadea. Para calcular unha permutación concrete se irá calculando o resto de dividir o número entre 2,3,4,.. o que nos dará os intercambios que teremos que facer e en qué posicións da cadea.
Pseudocódigo
n=factorial da lonxitude da cadea. i=0; Mentras (i<n) visualiza a permutación i i++ Fin-Mentras
Implementación en C
#include <stdio.h> #include <string.h> #define MAXELEMS 50 int p[MAXELEMS]; int fac(int n) { if (n==0) return 1; else return n*fac(n-1); } void inserta_p(char *c,int a,int b) { char t; t=c[b]; memmove(&c[a+1],&c[a],b-a); c[a]=t; } void calcula_permuta(int num) { int div=2; int x=0; while(num>0) { p[x]=num%div; num=num/div; div++; x++; } p[x]=-1; } char *efectua_permuta(char *cad,char *cadp) { int x,i; int len; strcpy(cadp,cad); len=strlen(cadp)-1; for(x=0;p[x]>=0;x++); x--; while(x>=0) { inserta_p(cadp,len-(x+1),len-(x+1)+p[x]); x--; } return cadp; } char *permuta_x(char *cad,char *cadp,int n) { calcula_permuta(n); return efectua_permuta(cad,cadp); } void permuta2(char *cad) { int i; int n=strlen(cad); char buffer[256]; n=fac(n); for(i=0;i<n;i++) printf("%s\n",permuta_x(cad,buffer,i)); } int main(int argc,char *argv[]) { int c; char buffer[256]; if (argc!=2) printf("USO: permuta cadenadeelementos\n"); else { permuta2(argv[1]); } return 0; }



