#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 */
+} t_BlockSortData;
+
+typedef struct _bs_t_ {
+ t_BlockSortData *array;
+ unsigned long int *ord;
+ unsigned long int len;
} 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;
- 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;
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)
+{
+ 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[])
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;
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;
}