]> git.llucax.com Git - z.facultad/75.06/jacu.git/blobdiff - otros/blocksorting/bs.c
* Agrego bs_restore para rehacer el array original.
[z.facultad/75.06/jacu.git] / otros / blocksorting / bs.c
index e5dd16f84866bcb190bf047983f94963bcdfe8ac..13b7824e46986dff9f50cd057e9c8c873a2c269d 100644 (file)
@@ -5,20 +5,40 @@
 #include <stdlib.h>
 #include <stdio.h>
 
 #include <stdlib.h>
 #include <stdio.h>
 
-typedef struct _bs_t_ {
+typedef struct _bs_data_t_ {
        unsigned long int pos_inicial;
        unsigned long int pos_final;
        unsigned long int pos_orden;
        char ord; /* indice si esta ordenada */
        unsigned long int pos_inicial;
        unsigned long int pos_final;
        unsigned long int pos_orden;
        char ord; /* indice si esta ordenada */
+} t_BlockSortData;
+
+typedef struct _bs_t_ {
+       t_BlockSortData *array;
+       unsigned long int *ord;
+       unsigned long int len;
 } t_BlockSort;
 
 } t_BlockSort;
 
-char es_menor(char *data, t_BlockSort *array, int n, int i, int j)
+typedef struct _bs_decode_t_ {
+       char c;
+       unsigned long int pos;
+} t_BlockSortDecode;
+
+int _compare(const void *d1, const void *d2) {
+       t_BlockSortDecode *s1, *s2;
+
+       s1 = (t_BlockSortDecode *)d1;
+       s2 = (t_BlockSortDecode *)d2;
+
+       return (s1->c - s2->c);
+}
+
+char es_menor(char *data, t_BlockSort *bs, int i, int j)
 {
        unsigned long int pi, pj, k;
 
 {
        unsigned long int pi, pj, k;
 
-       for(k=0; k<n; k++) {
-               pi = (array[i].pos_inicial+k)%n;
-               pj = (array[j].pos_inicial+k)%n;
+       for(k=0; k<bs->len; k++) {
+               pi = (bs->array[i].pos_inicial+k)%bs->len;
+               pj = (bs->array[j].pos_inicial+k)%bs->len;
 
                if (data[pi] > data[pj]) return 0;
                if (data[pi] < data[pj]) return 1;
 
                if (data[pi] > data[pj]) return 0;
                if (data[pi] < data[pj]) return 1;
@@ -27,60 +47,102 @@ char es_menor(char *data, t_BlockSort *array, int n, int i, int j)
        return 0;
 }
 
        return 0;
 }
 
-void generar_array(char *data, t_BlockSort *array, unsigned long int n)
+void generar_array(char *data, t_BlockSort *bs)
 {
        int i;
 {
        int i;
-       for(i=0; i<n; i++) {
-               array[i].pos_inicial = i;
-               array[i].pos_final = (i+n-1)%n;
-               array[i].pos_orden = 0;
-               array[i].ord = 0;
+       for(i=0; i<bs->len; i++) {
+               bs->array[i].pos_inicial = i;
+               bs->array[i].pos_final = (i+bs->len-1)%bs->len;
+               bs->array[i].pos_orden = 0;
+               bs->array[i].ord = 0;
        }
 }
 
        }
 }
 
-void ordenar_array(char *data, t_BlockSort *array, unsigned long int n)
+void ordenar_array(char *data, t_BlockSort *bs)
 {
        unsigned long int i, j, min;
 {
        unsigned long int i, j, min;
-       for(i=0; i<n; i++) {
+
+       for(i=0; i<bs->len; i++) {
                min = -1;
                min = -1;
-               for(j=0; j<n; j++) {
-                       if (array[j].ord) continue;
-                       if ((min==-1) || (es_menor(data, array, n, j, min)))
+               for(j=0; j<bs->len; j++) {
+                       if (bs->array[j].ord) continue;
+                       if ((min==-1) || (es_menor(data, bs, j, min)))
                                min = j;
                }
 
                                min = j;
                }
 
-               array[min].ord = 1;
-               array[min].pos_orden = i;
+               bs->array[min].ord = 1;
+               bs->array[min].pos_orden = i;
+
+               bs->ord[i] = min;
        }
 }
 
        }
 }
 
-int generar_salida(char *data, t_BlockSort *array, char *salida, int n)
+int generar_salida(char *data, t_BlockSort *bs, char *salida)
 {
 {
-       unsigned long int i, j, k;
+       unsigned long int i, k;
        k=-1;
        k=-1;
-       for(i=0; i<n; i++) {
-               for(j=0; j<n; j++) {
-                       if (array[j].pos_orden == i) {
-                               salida[i] = data[array[j].pos_final];
-                               if (array[j].pos_inicial == 0) k = i;
-                       }
-               }
+       for(i=0; i<bs->len; i++) {
+               salida[i] = data[bs->array[bs->ord[i]].pos_final];
+               if (bs->array[bs->ord[i]].pos_inicial == 0) k = i;
        }
        }
-
        return k;
 }
 
        return k;
 }
 
-void block_sorting(char *in, char *out, unsigned long int *k, unsigned long int len)
+void bs_solve(char *in, char *out, t_BlockSort *bs, unsigned long int *k, unsigned int leido)
+{
+       unsigned int l;
+       l = bs->len;
+       /* Hack para pedasos menores a la pagina */
+       if (leido < bs->len) bs->len = leido;
+       
+       generar_array(in, bs);
+       ordenar_array(in, bs);
+       (*k) = generar_salida(in, bs, out);
+
+       bs->len = l;
+}
+
+void bs_restore(char *dst, char *c, unsigned long int k, unsigned long int len)
 {
 {
-       t_BlockSort *array;
+       unsigned long int i, current;
+       t_BlockSortDecode *in;
 
 
-       array = malloc(sizeof(t_BlockSort)*len);
+       in = malloc(sizeof(t_BlockSortDecode)*len);
 
 
-       generar_array(in, array, len);
-       ordenar_array(in, array, len);
-       (*k) = generar_salida(in, array, out, len);
+       for(i=0; i<len; i++) {
+               in[i].c = c[i];
+               in[i].pos = i;
+       }
+
+       qsort(in, len, sizeof(t_BlockSortDecode), _compare);
+       
+       current = k;
+       i=0;
+       do {
+               dst[i++] = in[current].c;
+               current = in[current].pos;
+       } while (current != k);
+       free(in);
+}
+
+t_BlockSort *bs_create(unsigned int len)
+{
+       t_BlockSort *tmp;
+
+       tmp = malloc(sizeof(t_BlockSort));
+       tmp->array = malloc(sizeof(t_BlockSortData)*len);
+       tmp->ord = malloc(sizeof(unsigned long int)*len);
+       tmp->len = len;
 
 
-       free(array);
+       return tmp;
+}
+
+
+void bs_destroy(t_BlockSort *bs)
+{
+       free(bs->array);
+       free(bs->ord);
+       free(bs);
 }
 
 int main(int argc, char *argv[])
 }
 
 int main(int argc, char *argv[])
@@ -89,7 +151,9 @@ int main(int argc, char *argv[])
        char *salida;
        unsigned long int len, i, k;
        FILE *fp;
        char *salida;
        unsigned long int len, i, k;
        FILE *fp;
-
+       char c;
+       t_BlockSort *bs;
+       
        if (argc != 3) {
                printf("Modo de uso : %s <archivo datos> <tamaño pagina>\n", argv[0]);
                return 0;
        if (argc != 3) {
                printf("Modo de uso : %s <archivo datos> <tamaño pagina>\n", argv[0]);
                return 0;
@@ -99,17 +163,27 @@ int main(int argc, char *argv[])
        len = atoi(argv[2]);
 
        data = malloc(sizeof(char)*len);
        len = atoi(argv[2]);
 
        data = malloc(sizeof(char)*len);
-       salida = malloc(sizeof(char)*len);
-       memset(salida, 0, len*sizeof(char));
+       salida = malloc(sizeof(char)*(len+1));
 
 
-       for(i=0; i<len; i++)
-               data[i] = fgetc(fp);
+       salida[len] = '\0';
+       bs = bs_create(len);
 
 
-       fclose(fp);
+       while ((c = fgetc(fp)) != EOF) {
+               i = 0;
+               while ((c!=EOF) && (i < len)) {
+                       data[i++] = c;
+                       c = fgetc(fp);
+               }
+               bs_solve(data, salida, bs, &k, i);
 
 
-       block_sorting(data, salida, &k, len);
+               /* XXX ACA SALIDA DEBERIA PASAR A LA SIGUIENTE ETAPA XXX */
+               printf("%s -> %ld\n", salida, k);
+       }
+       fclose(fp);
+       bs_destroy(bs);
 
 
-       printf("Salida = (%s) con k=%ld\n", salida, k);
+       free(data);
+       free(salida);
        return 0;
 }
 
        return 0;
 }