]> git.llucax.com Git - z.facultad/75.06/jacu.git/blobdiff - otros/blocksorting/bs.c
Reemplazo printf() por fprintf(stderr) para hacer pruebas.
[z.facultad/75.06/jacu.git] / otros / blocksorting / bs.c
index e5dd16f84866bcb190bf047983f94963bcdfe8ac..bf39971012a9e72b11718c2fe7b923d792104700 100644 (file)
@@ -1,24 +1,29 @@
 
+#include "bs.h"
+
 /* Block Sorting Optimizado en memoria! */
 
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
+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;
 
-typedef struct _bs_t_ {
-       unsigned long int pos_inicial;
-       unsigned long int pos_final;
-       unsigned long int pos_orden;
-       char ord; /* indice si esta ordenada */
-} t_BlockSort;
+       s1 = (t_BlockSortDecode *)d1;
+       s2 = (t_BlockSortDecode *)d2;
 
-char es_menor(char *data, t_BlockSort *array, int n, int i, int j)
+       return (s1->c - s2->c);
+}
+
+char es_menor(char *data, t_BlockSort *bs, int i, int j)
 {
        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;
@@ -27,90 +32,101 @@ char es_menor(char *data, t_BlockSort *array, int n, int i, int j)
        return 0;
 }
 
-void generar_array(char *data, t_BlockSort *array, unsigned long int n)
+void generar_array(char *data, t_BlockSort *bs)
 {
        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;
-       for(i=0; i<n; i++) {
+
+       for(i=0; i<bs->len; i++) {
                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;
                }
 
-               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;
-       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;
 }
 
-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)
 {
-       t_BlockSort *array;
-
-       array = malloc(sizeof(t_BlockSort)*len);
-
-       generar_array(in, array, len);
-       ordenar_array(in, array, len);
-       (*k) = generar_salida(in, array, out, len);
-
-       free(array);
+       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;
 }
 
-int main(int argc, char *argv[])
+void bs_restore(char *dst, char *c, unsigned long int k, unsigned long int len)
 {
-       char *data; 
-       char *salida;
-       unsigned long int len, i, k;
-       FILE *fp;
-
-       if (argc != 3) {
-               printf("Modo de uso : %s <archivo datos> <tamaƱo pagina>\n", argv[0]);
-               return 0;
-       }
+       unsigned long int i, current;
+       t_BlockSortDecode *in;
 
-       fp = fopen(argv[1], "r");
-       len = atoi(argv[2]);
+       in = malloc(sizeof(t_BlockSortDecode)*len);
 
-       data = malloc(sizeof(char)*len);
-       salida = malloc(sizeof(char)*len);
-       memset(salida, 0, len*sizeof(char));
+       for(i=0; i<len; i++) {
+               in[i].c = c[i];
+               in[i].pos = i;
+       }
 
-       for(i=0; i<len; i++)
-               data[i] = fgetc(fp);
+       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);
+}
 
-       fclose(fp);
+t_BlockSort *bs_create(unsigned long int len)
+{
+       t_BlockSort *tmp;
 
-       block_sorting(data, salida, &k, len);
+       tmp = malloc(sizeof(t_BlockSort));
+       tmp->array = malloc(sizeof(t_BlockSortData)*len);
+       tmp->ord = malloc(sizeof(unsigned long int)*len);
+       tmp->len = len;
 
-       printf("Salida = (%s) con k=%ld\n", salida, k);
-       return 0;
+       return tmp;
 }
 
 
+void bs_destroy(t_BlockSort *bs)
+{
+       free(bs->array);
+       free(bs->ord);
+       free(bs);
+}
+