Dadas dos cadenas de caracteres, C1 y C2, con N caracteres cada una, se trata de encontrar la longitud de la subcadena más larga común a las dos cadenas, pudiendo haber huecos en los caracteres seleccionados en las cadenas.
Por ejemplo, dadas “abbcb” y “abcab” la longitud es 4, y corresponde a la subcadena “abca”, que se encuentra en las dos cadenas en varias formas: “ab-cb” y “abc-b”, o “a-bcb” y “abc-b”.
Se resuelven varios problemas. Para cada problema la función a paralelizar tiene par\'ametros:
Input parameter:
-int N: número de elementos de cada cadena
-int *C1, *C2: las dos cadenas
Return:
int longitud de la subcadena común más larga
La entrada tiene en la primera línea el número de problemas. Para cada problema hay una línea con tres valores: N, la semilla para la generación aleatoria, número de caracteres distintos a incluir en las cadenas.
4 12 2 7 19800 2 25 19400 15 27 19410 5 24
/* CPP_CONTEST=2019Enero CPP_PROBLEM=D CPP_LANG=CPP+OPENMP CPP_PROCESSES_PER_NODE=calisto 1 */ #include <stdio.h> #include <stdlib.h> #include <omp.h> void escribirint(int *m, int N,int M) { //solo para DEBUG int i, j; for (i = 0; i < N; i++) { for (j = 0; j < M; j++) printf("%d ", m[i * M + j]); printf("\n"); } printf("\n"); } int sec(int n,char *C1,char *C2) { int dim=n+1; //fila y columna 0 para casos base int resul; int *T=(int*) calloc(sizeof(int),dim*dim); //tabla para programación dinámica for(int i=0;i<dim;i++) //caso base fila T[i]=0; for(int i=1;i<dim;i++) //caso base columna T[i*dim]=0; for (int i = 1; i <dim; i++) { for(int j=1;j<dim;j++) { //máximo de la fila y columna anterior int maximo=(T[(i-1)*dim+j]>T[i*dim+j-1]?T[(i-1)*dim+j]:T[i*dim+j-1]); //si los elementos de las cadenas coinciden y añadiendo 1 al valor en la diagonal //anterior es mayor que el máximo, se actualiza if(C1[i-1]==C2[j-1] && T[(i-1)*dim+j-1]+1>maximo) maximo=T[(i-1)*dim+j-1]+1; T[i*dim+j]=maximo; } } #ifdef DEBUG escribirint(T,dim,dim); #endif //la longitud de la cadena más larga es el último valor en la tabla de programación dinámica resul=T[dim*dim-1]; delete[] T; return resul; }
esquema-openmp.cpp (no modificable, lo usa mooshak para entrada/salida y evaluación, se proporciona para experimentación en local)
#include <stdlib.h> #include <stdio.h> #include <sys/time.h> #include <omp.h> #include <signal.h> #include <unistd.h> //Prueba de Metodología de la Programación Paralela //enero 2019 //Subcadena común más larga entre dos cadenas de caracteres. //Esquema para entrada/salida, validación y toma de tiempos void generar(char *m, int t,int numcar) { int i; for (i = 0; i < t; i++) { m[i] =(char) ((int) (((1. * rand()) / RAND_MAX)*numcar)+'a'); } } void escribir(char *m, int N,int M) { int i, j; for (i = 0; i < N; i++) { for (j = 0; j < M; j++) printf("%c", m[i * M + j]); printf("\n"); } printf("\n"); } /* c c mseconds - returns elapsed milliseconds since Jan 1st, 1970. c */ long long mseconds(){ struct timeval t; gettimeofday(&t, NULL); return t.tv_sec*1000 + t.tv_usec/1000; } static void alarm_handler(int sig) { fprintf(stderr, "Time Limit Exceeded\n"); abort(); } extern int sec(int n,char *C1,char *C2); int main(int argc,char *argv[]) { int N; //tamaño cadenas char *C1,*C2; //cadenas int cuantos; //número de problemas int semilla; //semilla para generación aleatoria int numcar; //número de caracteres distintos a generar long long ti,tf,tt=0; FILE *stats_file = fopen("stats", "w"); struct sigaction sact; sigemptyset(&sact.sa_mask); sact.sa_flags = 0; sact.sa_handler = alarm_handler; sigaction(SIGALRM, &sact, NULL); alarm(10); /* time limit */ scanf("%d",&cuantos); for(int i=0;i<cuantos;i++) { scanf("%d",&N); scanf("%d",&semilla); scanf("%d",&numcar); C1 = (char *) calloc(sizeof(char),N); C2 = (char *) calloc(sizeof(char),N); srand(semilla); generar(C1,N,numcar); generar(C2,N,numcar); #ifdef DEBUG escribir(C1,1,N); escribir(C2,1,N); #endif ti=mseconds(); printf("%d\n",sec(N,C1,C2)); tf=mseconds(); if(i!=0) tt+=tf-ti; free(C1); free(C2); } fprintf(stats_file, "%Ld\n", tt); fclose(stats_file); return 0; }