Frage

Ich habe eine Struktur:

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

typedef struct pkt_ pkt;

Eine Tabelle dieser Strukturen:

pkt *tab_pkt;

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

Was ich tun möchte, ist tab_pkt von tab_pkt.alfa und tab_pkt.r zu sortieren:

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

Wo porownaj eine Funktion vergleichen, aber wie es zu schreiben? Hier ist meine „Skizze“ davon:

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;
}
War es hilfreich?

Lösung

So etwas sollte funktionieren:

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;
}

Bleiben Sie weg von dummen Tricks wie:

return pkt_a->r_kw - pkt_b->r_kw;

, die nicht-normalisierten Werte zurückgeben, zu lesen sind verwirrend, wird für Gleitkommazahlen nicht richtig funktionieren, und manchmal heikele Ecke Fälle, die nicht richtig, auch Werte für integer arbeiten.

Andere Tipps

Es gibt zwei Teile, um das Problem - wie Sie den Code zu schreiben, und wie die Pakettypen zu vergleichen. Sie müssen sicherstellen, dass Sie immer einen Wert zurückgeben. Der Code soll auch immer so sein, dass:

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

Ihr Umriss Vergleich nicht behandelt Fälle wie:

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

Es gibt ein weiteres Problem - ist es angebracht, Punktwerte für die exakte Gleichheit zu vergleichen schwimmend? Das wird auf der Anwendung ab.

Mechanisch, haben Sie die const void-Zeiger auf const Struktur Zeiger zu konvertieren. Ich benutze die explizite Umwandlung - C ++ erfordert es, und ich versuche, meinen Code akzeptabel zu einem C ++ Compiler selbst wenn es wirklich C-Code zu machen

.
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;
 }

Das funktioniert nicht mit den Bits befassen, die ich nicht lösen kann, da ich nicht zu den erforderlichen Informationen Partei bin. Man beachte, daß im allgemeinen multidimensionalen Objekten (wie komplexe Zahlen oder (x, y) oder (x, y, z) Koordinaten) kann nicht einfach für mehr verglichen werden, als oder kleiner als oder gleich.

Ja, ich bin das Sortieren von alfa und r_kw entscheidet, ob pkt erste ist (erster Wert die größten (oder kleinsten) alfa und r_kw glaube ich). Das ist, wie ich das Problem zu verstehen, ich bin nicht 100% sicher.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top