]> git.llucax.com Git - z.facultad/75.06/jacu.git/blob - otros/blocksorting/bs.c
Cambio para que tome datos de la entrada estandar, espero que no joda.
[z.facultad/75.06/jacu.git] / otros / blocksorting / bs.c
1
2 #include "bs.h"
3
4 /* Block Sorting Optimizado en memoria! */
5
6 typedef struct _bs_decode_t_ {
7         char c;
8         unsigned long int pos;
9 } t_BlockSortDecode;
10
11 int _compare(const void *d1, const void *d2) {
12         t_BlockSortDecode *s1, *s2;
13
14         s1 = (t_BlockSortDecode *)d1;
15         s2 = (t_BlockSortDecode *)d2;
16
17         return (s1->c - s2->c);
18 }
19
20 char es_menor(char *data, t_BlockSort *bs, int i, int j)
21 {
22         unsigned long int pi, pj, k;
23
24         for(k=0; k<bs->len; k++) {
25                 pi = (bs->array[i].pos_inicial+k)%bs->len;
26                 pj = (bs->array[j].pos_inicial+k)%bs->len;
27
28                 if (data[pi] > data[pj]) return 0;
29                 if (data[pi] < data[pj]) return 1;
30         }
31
32         return 0;
33 }
34
35 void generar_array(char *data, t_BlockSort *bs)
36 {
37         int i;
38         for(i=0; i<bs->len; i++) {
39                 bs->array[i].pos_inicial = i;
40                 bs->array[i].pos_final = (i+bs->len-1)%bs->len;
41                 bs->array[i].pos_orden = 0;
42                 bs->array[i].ord = 0;
43         }
44 }
45
46 void ordenar_array(char *data, t_BlockSort *bs)
47 {
48         unsigned long int i, j, min;
49
50         for(i=0; i<bs->len; i++) {
51                 min = -1;
52                 for(j=0; j<bs->len; j++) {
53                         if (bs->array[j].ord) continue;
54                         if ((min==-1) || (es_menor(data, bs, j, min)))
55                                 min = j;
56                 }
57
58                 bs->array[min].ord = 1;
59                 bs->array[min].pos_orden = i;
60
61                 bs->ord[i] = min;
62         }
63 }
64
65 int generar_salida(char *data, t_BlockSort *bs, char *salida)
66 {
67         unsigned long int i, k;
68         k=-1;
69         for(i=0; i<bs->len; i++) {
70                 salida[i] = data[bs->array[bs->ord[i]].pos_final];
71                 if (bs->array[bs->ord[i]].pos_inicial == 0) k = i;
72         }
73         return k;
74 }
75
76 void bs_solve(char *in, char *out, t_BlockSort *bs, unsigned long int *k, unsigned int leido)
77 {
78         unsigned int l;
79         l = bs->len;
80         /* Hack para pedasos menores a la pagina */
81         if (leido < bs->len) bs->len = leido;
82         
83         generar_array(in, bs);
84         ordenar_array(in, bs);
85         (*k) = generar_salida(in, bs, out);
86
87         bs->len = l;
88 }
89
90 void bs_restore(char *dst, char *c, unsigned long int k, unsigned long int len)
91 {
92         unsigned long int i, current;
93         t_BlockSortDecode *in;
94
95         in = malloc(sizeof(t_BlockSortDecode)*len);
96
97         for(i=0; i<len; i++) {
98                 in[i].c = c[i];
99                 in[i].pos = i;
100         }
101
102         qsort(in, len, sizeof(t_BlockSortDecode), _compare);
103         
104         current = k;
105         i=0;
106         do {
107                 dst[i++] = in[current].c;
108                 current = in[current].pos;
109         } while (current != k);
110         free(in);
111 }
112
113 t_BlockSort *bs_create(unsigned long int len)
114 {
115         t_BlockSort *tmp;
116
117         tmp = malloc(sizeof(t_BlockSort));
118         tmp->array = malloc(sizeof(t_BlockSortData)*len);
119         tmp->ord = malloc(sizeof(unsigned long int)*len);
120         tmp->len = len;
121
122         return tmp;
123 }
124
125
126 void bs_destroy(t_BlockSort *bs)
127 {
128         free(bs->array);
129         free(bs->ord);
130         free(bs);
131 }
132