Ver Mensaje Individual
  #13 (permalink)  
Antiguo 08/07/2016, 12:52
aguml
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: ¿Se puede optimizar el siguiente codigo?

Bueno, al final he encontrado una manera de codear lo que quiero y optimizando muy mucho el tiempo aunque ocupando mas memoria. Este es el codigo:
Código C:
Ver original
  1. //---------------------------------------------------------------------------
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include <errno.h>
  7. #include <limits.h>
  8. #define SIZEMAX 1024
  9.  
  10.  
  11. typedef enum {
  12.     STR2INT_SUCCESS,
  13.     STR2INT_OVERFLOW,
  14.     STR2INT_UNDERFLOW,
  15.     STR2INT_INCONVERTIBLE
  16. } str2int_errno;
  17.  
  18. int largoHash;
  19. //---------------------------------------------------------------------------
  20.  
  21. void clean(void)
  22. {
  23.     char a;
  24.     while(getchar()!='\n');
  25. }
  26. //---------------------------------------------------------------------------
  27.  
  28. void ObtenerRutas(char *pathOrigen1,char *pathOrigen2,char *pathDestino2,int *largoHash)
  29. {
  30.     int largo;
  31.  
  32.     printf("Introduce la ruta completa hacia el primer archivo:\n\t");
  33.     fgets(pathOrigen1,SIZEMAX,stdin);
  34.     largo=strlen(pathOrigen1);
  35.     if(pathOrigen1[largo-1]!='\n'){
  36.         clean();
  37.         printf("Ruta demasiado larga.\n");
  38.     }else{
  39.         pathOrigen1[largo-1]='\0';
  40.     }
  41.     printf("Introduce la ruta completa hacia el segundo archivo:\n\t");
  42.     fgets(pathOrigen2,SIZEMAX,stdin);
  43.     largo=strlen(pathOrigen2);
  44.     if(pathOrigen2[largo-1]!='\n'){
  45.         clean();
  46.         printf("Ruta demasiado larga.\n");
  47.     }else{
  48.         pathOrigen2[largo-1]='\0';
  49.     }
  50.     printf("Introduce la ruta completa para el archivo de salida:\n\t");
  51.     fgets(pathDestino2,SIZEMAX,stdin);
  52.     largo=strlen(pathDestino2);
  53.     if(pathDestino2[largo-1]!='\n'){
  54.         clean();
  55.         printf("Ruta demasiado larga.\n");
  56.     }else{
  57.         pathDestino2[largo-1]='\0';
  58.     }
  59.     printf("Introduce el numero de caracteres del hash: ");
  60.     scanf("%d",largoHash);
  61. }
  62. //---------------------------------------------------------------------------
  63.  
  64. //Para convertir el parametro del largo del hash de cadena a entero
  65. str2int_errno str2int(int *out, char *s, int base) {
  66.     char *end;
  67.     long l;
  68.  
  69.     if (s[0] == '\0' || isspace((unsigned char) s[0]))
  70.         return STR2INT_INCONVERTIBLE;
  71.     errno = 0;
  72.     l = strtol(s, &end, base);
  73.  
  74.     if (l > INT_MAX || (errno == ERANGE && l == LONG_MAX))
  75.         return STR2INT_OVERFLOW;
  76.     if (l < INT_MIN || (errno == ERANGE && l == LONG_MIN))
  77.         return STR2INT_UNDERFLOW;
  78.     if (*end != '\0')
  79.         return STR2INT_INCONVERTIBLE;
  80.     *out = l;
  81.     return STR2INT_SUCCESS;
  82. }
  83. //---------------------------------------------------------------------------
  84.  
  85. int CheckParams(int nParametros, char *parametros[], char *pathOrigen1,char *pathOrigen2,char *pathDestino2,int *largoHash)
  86. {
  87.     str2int_errno error_param_hash;
  88.     char mensaje[SIZEMAX];
  89.  
  90.     if(nParametros == 5){
  91.         strcpy(pathOrigen1,parametros[1]);
  92.         strcpy(pathOrigen2,parametros[2]);
  93.         strcpy(pathDestino2,parametros[3]);
  94.         error_param_hash=str2int(largoHash,parametros[4],10);
  95.         switch(error_param_hash){
  96.             case STR2INT_OVERFLOW:
  97.                 strcpy(mensaje,"STR2INT_OVERFLOW");
  98.             break;
  99.  
  100.             case STR2INT_UNDERFLOW:
  101.                 strcpy(mensaje,"STR2INT_UNDERFLOW");
  102.             break;
  103.  
  104.             case STR2INT_INCONVERTIBLE:
  105.                 strcpy(mensaje,"STR2INT_INCONVERTIBLE");
  106.             break;
  107.         }
  108.         if(error_param_hash != STR2INT_SUCCESS){
  109.             printf("Error en el parametro para el largo del hash. Error: %s\n",mensaje);
  110.             return -1;
  111.         }
  112.         if(*largoHash < 0){
  113.             printf("El valor asignado al largo del hash no puede ser menor que '0'.\nSi no hay hash ponga '0'.\n");
  114.             return -2;
  115.         }
  116.     }else if(nParametros > 1){
  117.         printf("parametros incorrectos.\n");
  118.         return -3;
  119.     }else{
  120.         ObtenerRutas(pathOrigen1,pathOrigen2,pathDestino2,largoHash);
  121.     }
  122.     return 0;
  123. }
  124. //---------------------------------------------------------------------------
  125.  
  126. void DescartarElemento(char **buffer,int pos,int *nElementos)
  127. {
  128.     int i;
  129.  
  130.     for(i=pos; i < *nElementos-1; i++){
  131.         buffer[i]=buffer[i+1];
  132.     }
  133.     (*nElementos)--;
  134. }
  135. //---------------------------------------------------------------------------
  136.  
  137. int CrearFicheroOrdenado(char **bufferFile1,char **bufferFile2,char *pathDestino,int largoHash,int nElementosBufferFile1,int nElementosBufferFile2)
  138. {
  139.     FILE *destino=NULL;
  140.     int encontrado,noEncontrados=0;
  141.     int i,j,retval=0;
  142.     char **arrayAuxiliar;
  143.  
  144.     destino=fopen(pathDestino,"w");
  145.  
  146.     if(destino == NULL)
  147.         return -1;
  148.  
  149.     printf("Ha comenzado el proceso. No cierre esta ventana hasta que termine el proceso.\n");
  150.     arrayAuxiliar=malloc(nElementosBufferFile2 * sizeof(char**));
  151.  
  152.     if(arrayAuxiliar == NULL){
  153.         fclose(destino);
  154.         remove(pathDestino);
  155.         return -2;
  156.     }
  157.  
  158.     memcpy(arrayAuxiliar,bufferFile2,nElementosBufferFile2 * sizeof(char**));
  159.  
  160.     for(i=0; i < nElementosBufferFile1; i++){
  161.         encontrado=0;
  162.         for(j=0; j < nElementosBufferFile2; j++){
  163.             if(strcmp(bufferFile1[i],arrayAuxiliar[j])==0){
  164.                 encontrado=1;
  165.                 break;
  166.             }
  167.         }
  168.         if(encontrado==1){
  169.             fputs(arrayAuxiliar[j],destino);
  170.             DescartarElemento(arrayAuxiliar,j,&nElementosBufferFile2);
  171.         }else{
  172.             fputs("\n",destino);
  173.             noEncontrados++;
  174.         }
  175.     }
  176.     free(arrayAuxiliar);
  177.     fclose(destino);
  178.  
  179.     if(noEncontrados > 0)
  180.         retval=noEncontrados;
  181.  
  182.     return retval;
  183. }
  184. //---------------------------------------------------------------------------
  185.  
  186. void LiberarMemoria(char **buffer,int nlines)
  187. {
  188.     int index;
  189.  
  190.     if(buffer != NULL){
  191.         for(index=0;index < nlines;index++)
  192.             free(buffer[index]);
  193.         free(buffer);
  194.         buffer=NULL;
  195.     }
  196. }
  197. //---------------------------------------------------------------------------
  198.  
  199. char** CargarFicheroEnMemoria(char *path,int *nlines)
  200. {
  201.     int largo;
  202.     char aux[SIZEMAX];
  203.     char **pbuffer,**paux;
  204.     FILE *origen;
  205.     origen=fopen(path,"r");
  206.  
  207.     *nlines=0;
  208.     if(origen != NULL){
  209.         pbuffer=NULL;
  210.         do{
  211.             memset(aux,'\0',SIZEMAX);
  212.             fgets(aux,SIZEMAX,origen);
  213.             if(!feof(origen)){
  214.                 largo=strlen(aux);
  215.                 (*nlines)++;
  216.                 paux=(char**)realloc(pbuffer,*nlines*sizeof(char**));
  217.                 if(paux != NULL){
  218.                     pbuffer=paux;
  219.                     pbuffer[*nlines-1]=(char*)malloc(sizeof(char*)*largo);
  220.                     strcpy(pbuffer[*nlines-1],aux);
  221.                 }else{
  222.                     printf("No hay suficiente memoria disponible para volcar el archivo.\n");
  223.                     LiberarMemoria(pbuffer,*nlines-1);
  224.                 }
  225.             }
  226.         }while(!feof(origen));
  227.         fclose(origen);
  228.     }
  229.     return pbuffer;
  230. }
  231. //---------------------------------------------------------------------------
  232.  
  233. /* funcion para comparar strings de C para qsort */
  234. int cstring_cmp(const void *a, const void *b)
  235. {
  236.     const char **ia = (const char **)a;
  237.     const char **ib = (const char **)b;
  238.     return strcmp(*ia+largoHash, *ib+largoHash);
  239. }
  240. //---------------------------------------------------------------------------
  241.  
  242. //Se puede usar con parametros tambien
  243. int main(int argc, char* argv[])
  244. {
  245.     char pathOrigen1[SIZEMAX];
  246.     char pathOrigen2[SIZEMAX];
  247.     char pathDestino[SIZEMAX];
  248.     char **bufferFile1,**bufferFile2;
  249.     int nElementosFile1,nElementosFile2,retval;
  250.  
  251.     if(CheckParams(argc,argv,pathOrigen1,pathOrigen2,pathDestino,&largoHash) == 0){
  252.         if((bufferFile1=CargarFicheroEnMemoria(pathOrigen1,&nElementosFile1)) > 0){
  253.             if((bufferFile2=CargarFicheroEnMemoria(pathOrigen2,&nElementosFile2)) > 0){
  254.                 //Ordeno los elementos
  255.                 qsort(bufferFile2, nElementosFile2, sizeof(char *), cstring_cmp);
  256.                 retval=CrearFicheroOrdenado(bufferFile1,bufferFile2,pathDestino,largoHash,nElementosFile1,nElementosFile2);
  257.  
  258.                 switch(retval){
  259.                     case 0:
  260.                         printf("Proceso finalizado correctamente.\n");
  261.                         break;
  262.                     case -1:
  263.                         printf("Proceso finalizado con errores.\n");
  264.                         printf("No se pudo abrir el archivo \"%s\".\n",pathOrigen2);
  265.                         break;
  266.                     case -2:
  267.                         printf("Proceso finalizado con errores.\n");
  268.                         printf("No se pudo obtener memoria suficiente.\n");
  269.                         break;
  270.                     default:
  271.                         printf("Proceso finalizado.\n");
  272.                         printf("No se encontraron %d entradas en \"%s\".\n",retval,pathOrigen2);
  273.                 }
  274.                 //Libero la memoria solicitada para guardar el archivo en ella
  275.                 LiberarMemoria(bufferFile2,nElementosFile2);
  276.             }
  277.             LiberarMemoria(bufferFile1,nElementosFile1);
  278.         }
  279.     }
  280.     system("pause");
  281.     return 0;
  282. }
  283. //---------------------------------------------------------------------------