Subcadena común más larga entre dos cadenas de caracteres. Versión OpenMP.

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.

Ficheros

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;
}
#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;
}