Ver Mensaje Individual
  #5 (permalink)  
Antiguo 09-12-2005, 16:50:07
Oscar Garcia
 
Mensajes: n/a
Predeterminado Re: qsort de FreeBSD y Linux ordenan distinto...!

El Fri, 09 Dec 2005 11:08:17 -0300, Horacio Castellini
<hcaste***fonosur.com.ar> escribió:
>Holas
> Me está surgiendo un problema con la portabilidad del qsort, supongamos que
>quiero ordenar un arreglo de estructuras...
>
>en caso de empate... es decir que comp_tema devuelve cero, tenía el
>prejuicio que ambas bibliotecas C ordenaban igual... pero no...
>
>Es decir en linux sale...
>
>a1 t1
>a3 t1
>a4 t1
>
>en cambio en FreeBSD
>
>a4 t1
>a1 t1
>a3 t1
>
>Como el oreden es crítico en mi caso... que solución puedo implementar para
>que esto no me suceda...


El problema principal es como interpreta cada librería la igualdad.
Parece que Linux (como debe ser) en caso de igualdad de elementos no
los intercambia. Sin embargo parece que FreeBSD sí que hace ese
intercambio en caso de igualdad.

Una implementación en C podría ser:

void cambia (int *a, int *b) {
int t=*a;
*a=*b;
*b=t;
}

void __qsort (int arr[], int ini, int fin) {
if (fin > ini + 1) {
int piv = arr[ini], l = ini + 1, r = fin;
while (l < r) {
if (arr[l] <= piv) {
l++;
} else {
cambia (&arr[l], &arr[--r]);
}
}
cambia (&arr[--l], &arr[beg]);
__qsort (arr, ini, l);
__qsort (arr, r, fin);
}
}

Ese "if (arr[l] <= piv)" puede cambiarse por un "if (arr[l] < piv)"
sin que se modifique el resultado final (en cuanto al orden de
ordenación), pero hace que ciertos elementos del mismo valor quizá
sean comparados e intercambiados entre sí. Por supuesto esa
comparación realmente es el valor que devuelve la función que tú has
creado cuando se usa la función qsort de la librería de C.

Si de verdad deseas que el resultado sea exactamente igual te aconsejo
que ordenes por TODOS los campos de tu estructura sin dejarte ninguno
(a ser posible deja la clave primaria para el último lugar).

Es la única forma de garantizar la exactitud en la salida en cualquier
plataforma y usando cualquier método de ordenación.

Tú has puesto solo dos elementos en tu estructura, pero supongo que
tendrás aún más (no creo que se llame "mail" una estructura que no
contiene el correo electrónico de un autor .

Tanto Azdo como Eduardo te han dado soluciones más prácticas. Yo te
agrego que compares todos y cada uno de los elementos de tu estructura
(por supuesto por prioridades: por ejemplo... primero nombre, luego
primer apellido, luego segundo apellido, etc).

Un saludo.

--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
Responder Con Cita