Pergunta

Eu tenho uma estrutura:

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

typedef struct pkt_ pkt;

Uma tabela destas estruturas:

pkt *tab_pkt;

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

O que eu quero fazer é tab_pkt ordenar por tab_pkt.alfa e tab_pkt.r:

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

Onde porownaj é uma função comparar, mas como escrevê-lo? Aqui é o meu "esboço" do mesmo:

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;
}
Foi útil?

Solução

Algo como isto deve 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;
}

Fique longe de truques bobos como:

return pkt_a->r_kw - pkt_b->r_kw;

que valores não-normalizado retorno, são confusas para ler, não vai funcionar corretamente para números de ponto flutuante, e às vezes temos casos de canto complicado que não funcionam corretamente, mesmo para valores inteiros.

Outras dicas

Há duas partes para o problema - como escrever o código, e como comparar os tipos de pacotes. Você deve garantir que você sempre retornar um valor. Seu código também deve ser sempre tal que:

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

A sua comparação esboço não lidar com 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

Há mais um problema - é apropriado para comparar valores de ponto flutuante de igualdade exata? Isso vai depender da sua aplicação.

Mecanicamente, você tem que converter os ponteiros void const aos ponteiros estrutura const. Eu uso a conversão explícita -. C ++ exige isso, e eu tento fazer o meu código aceitável para um compilador C ++, mesmo quando é realmente 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;
 }

Esta não lida com os bits que eu não posso resolver desde que eu não sou parte as informações necessárias. Note-se que, em, objectos multi-dimensionais gerais (tais como números complexos, ou (x, y) ou (x, y, z) coordenadas) não pode simplesmente ser comparados para uma maior ou menor do que ou igual a.

Sim, estou a classificação por alfa e r_kw decide se pacote é o primeiro (primeiro valor terá o maior (ou menor) alfa e r_kw eu acho). É assim que eu entendo o problema, eu não estou 100% de certeza.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top