2016-10-13 38 views
0

我正在尝试使用qsort对结构数组进行排序。我有一个看起来像这样的结构:排序绑定结构元素

typedef struct { 
    double score; 
    int player_num; 
} player_t; 

而且我已经创建了一个结构数组的六名球员是这样的:

player_t *players = malloc(6 * sizeof(player_t)); 

,我来自这两个数组插入如果数据:

int player_numbers[] = {1, 2, 3, 4, 5, 6}; 
double scores[] = {0.765, 0.454, 0.454, 0.345, 0.643, 0.532}; 

到目前为止,我正在尝试按照分数对这个结构数组进行排序,如果分数中有关系,那么必须对玩家数进行排序。我迄今为止得到这个输出,从排序分数:

Player 1: Score: 0.765 
Player 5: Score: 0.643 
Player 6: Score: 0.532 
Player 3: Score: 0.454 
Player 2: Score: 0.454 
Player 4: Score: 0.345 

当我我真正想要的是这样的:

Player 1: Score: 0.765 
Player 5: Score: 0.643 
Player 6: Score: 0.532 
Player 2: Score: 0.454 
Player 3: Score: 0.454 
Player 4: Score: 0.345 

借助于此Player 2Player 3互换位置,因为他们有相同的分数,所以他们各自的球员号码被排序。阵列的其余部分保持不变。

我到目前为止只是根据得分本身对结构阵列进行了排序,这些结果产生了第一个输出。我的代码如下所示:

#include <stdio.h> 
#include <stdlib.h> 

#define SIZE 6 

int scorecmp(const void *a, const void *b); 

typedef struct { 
    double score; 
    int player_num; 
} player_t; 

int 
main(int argc, char *argv[]) { 
    int i; 

    int player_numbers[] = {1, 2, 3, 4, 5, 6}; 
    double scores[] = {0.765, 0.454, 0.454, 0.345, 0.643, 0.532}; 

    player_t *players = malloc(SIZE * sizeof(player_t)); 

    for (i = 0; i < SIZE; i++) { 
     players[i].score = scores[i]; 
     players[i].player_num = player_numbers[i]; 
    } 

    qsort(players, SIZE, sizeof(*players), scorecmp); 

    for (i = 0; i < SIZE; i++) { 
     printf("Player %d: Score: %.3f\n", players[i].player_num, players[i].score); 
    } 

    free(players); 

    return 0; 
} 

int 
scorecmp(const void *x, const void *y) { 
    if ((*(double*)x > *(double*)y)) { 
     return -1; 
    } 
    if ((*(double*)x < *(double*)y)) { 
     return +1; 
    } 
    return 0; 
} 

有没有什么方法可以让我第二次排序并列scores,从使用player_num代替,并产生第二所需的输出?

任何帮助,将不胜感激。

+0

at'scorecmp':'return 0;' - >'return(((player_t *)x) - > player_num>((player_t *)y) - > player_num) - ((player_t *)x) - > player_num <((player_t *)y) - > player_num);' – BLUEPIXY

+0

@BLUEPIXY请不要张贴hacky答案作为评论。 – user694733

+0

你可以把它放在答案@BLUEPIXY中吗? – RoadRunner

回答

1

您排序的方式不正确。比较函数接收一个指向结构的指针,而不是指向结构成员的指针。

由分数排序正确的方法是在qsort函数使用这个比较函数:

int ComparePlayerScore(const void* ap , const void* bp) 
{ 
    const player_t* const a = ap; 
    const player_t* const b = bp; 

    if(a->score < b->score) 
    { 
     return -1; 
    } 
    else if(a->score > b->score) 
    { 
     return 1; 
    } 

    return 0; 
} 

如果你想确保具有相同分数的玩家都按字母顺序排序,你将需要另一个检查在排序功能。首先检查球员是否有相同的分数,然后按球员号码排序。

使用天真的方式来比较浮点,该功能将是:

if(a->score == b->score) 
{ 
    return CompareInt(a->player_num , b->player_num) 
} 
else if(a->score < b->score) 
{ 
    return -1; 
} 
else 
{ 
    return 1; 
} 

哪里CompareInt是另一个功能:

int CompareInt(const int a , const int b) 
{ 
    if(a < b) 
    { 
     return -1; 
    } 
    else if(a > b) 
    { 
     return 1; 
    } 

    return 0; 
} 

使用简单比较运算符来比较浮点可能会产生问题,请参阅:How should I do floating point comparison?

+0

谢谢。如果我创建一个新的比较函数来对'player_num'进行排序,我如何才能使它从'scores'中检测到关系?不仅仅是让比较函数根据玩家数量对整个数组进行排序? – RoadRunner

+0

@不,你需要提供一个比较'score'的函数,只有当它们相等时才比较'player_num'。所以你需要在一个函数中进行4次比较。 – user694733

+0

@RoadRunner查看更新。 – 2501