Pregunta

Tengo una estructura:

struct pkt_
{
  double x;
  double y;
  double alfa;
  double r_kw;
};

typedef struct pkt_ pkt;

Una tabla de estas estructuras:

pkt *tab_pkt;

tab_pkt = malloc(ilosc_pkt * sizeof(pkt));

Lo que quiero hacer es ordenar tab_pkt por tab_pkt.alfa y tab_pkt.r :

qsort(tab_pkt, ilosc_pkt, sizeof(pkt), porownaj);

Donde porownaj es una función de comparación, pero ¿cómo escribirla? Aquí está mi '' boceto '' de ella:

int porownaj(const void *pkt_a, const void *pkt_b)
{
  if (pkt_a.alfa > pkt_b.alfa && pkt_a.r_kw > pkt_b.r_kw) return 1;
  if (pkt_a.alfa == pkt_b.alfa && pkt_a.r_kw == pkt_b.r_kw) return 0;
  if (pkt_a.alfa < pkt_b.alfa && pkt_a.r_kw < pkt_b.r_kw) return -1;
}
¿Fue útil?

Solución

Algo como esto debería funcionar:

int porownaj(const void *p_a, const void *p_b)
{
  /* Need to store arguments in appropriate type before using */
  const pkt *pkt_a = p_a;
  const pkt *pkt_b = p_b;

  /* Return 1 or -1 if alfa members are not equal */
  if (pkt_a->alfa > pkt_b->alfa) return 1;
  if (pkt_a->alfa < pkt_b->alfa) return -1;

  /* If alfa members are equal return 1 or -1 if r_kw members not equal */
  if (pkt_a->r_kw > pkt_b->r_kw) return 1;
  if (pkt_a->r_kw < pkt_b->r_kw) return -1;

  /* Return 0 if both members are equal in both structures */
  return 0;
}

Manténgase alejado de trucos tontos como:

return pkt_a->r_kw - pkt_b->r_kw;

que devuelve valores no normalizados, es confuso de leer, no funcionará correctamente para números de coma flotante y, a veces, tiene casos de esquina difíciles que no funcionan correctamente incluso para valores enteros.

Otros consejos

El problema tiene dos partes: cómo escribir el código y cómo comparar los tipos de paquetes. Debe asegurarse de que siempre devuelve un valor. Su código también debe ser siempre tal que:

porownaj(&pkt_a, &pkt_b) == -porownaj(&pkt_b, &pkt_a)

Su comparación de esquema no maneja casos como:

pkt_a->alfa >  pkt_b->alfa && pkt_a->r_kw <= pkt_b->r_kw
pkt_a->alfa <  pkt_b->alfa && pkt_a->r_kw >= pkt_b->r_kw
pkt_a->alfa == pkt_b->alfa && pkt_a->r_kw != pkt_b->r_kw

Hay un problema más: ¿es apropiado comparar los valores de coma flotante para la igualdad exacta? Eso dependerá de su aplicación.

Mecánicamente, debe convertir los punteros vacíos constantes en punteros de estructura constante. Uso el reparto explícito: C ++ lo requiere y trato de hacer que mi código sea aceptable para un compilador de C ++, incluso cuando es realmente un código C.

int porownaj(const void *vp1, const void *vp2)
{
     const pkt *pkt_a = (const pkt *)vp1;
     const pkt *pkt_b = (const pkt *)vp2;

     if (pkt_a->alfa >  pkt_b->alfa && pkt_a->r_kw >  pkt_b->r_kw) return 1;
     if (pkt_a->alfa == pkt_b->alfa && pkt_a->r_kw == pkt_b->r_kw) return 0;
     if (pkt_a->alfa <  pkt_b->alfa && pkt_a->r_kw <  pkt_b->r_kw) return -1;
     return 0;
 }

Esto no trata con los bits que no puedo resolver ya que no soy parte de la información necesaria. Tenga en cuenta que, en general, los objetos multidimensionales (como números complejos, o (x, y) o (x, y, z) coordenadas) no se pueden comparar simplemente para mayor o menor que o igual a.

Sí, estoy ordenando por alfa y r_kw decide si pkt es el primero (el primer valor tendrá los alfa y r_kw más grandes (o más pequeños), creo). Así es como entiendo el problema, no estoy 100% seguro.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top