有没有办法在 C 中按多个变量对结构进行排序?
Is there a way to sort structs by multiple variables in C?
我必须编写一个函数来对数组中的结构进行排序。结构是:
#define MAX_USERNAME_LENGTH 16
typedef struct{
char username[MAX_USERNAME_LENGTH];
unsigned int rides;
unsigned int rank;
} driver;
程序从 .txt 文件加载数据并填充数组
driver driver_list[256]
我必须 driver_list 按等级和乘车次数排序。所以如果我的文件包含
//user rides rank
frank209 3 6
john76 7 6
harry99 2 2
bob77 5 2
输出必须显示:
john76 7 6
frank209 3 6
bob77 5 2
harry99 2 2
有办法吗?我已经尝试使用 2 个嵌套的选择排序,但在输出中我看到列表仅按等级或游乐设施排序。
感谢帮助
使用在header<stdlib.h>
中声明的标准函数qsort
并写一个user-defined比较函数。
给你。
#include <stdio.h>
#include <stdlib.h>
#define MAX_USERNAME_LENGTH 10
typedef struct
{
char username[MAX_USERNAME_LENGTH];
unsigned int rides;
unsigned int rank;
} driver;
int cmp( const void *left, const void *right )
{
const driver *a = ( const driver *)left;
const driver *b = ( const driver *)right;
if ( b->rank < a->rank )
{
return -1;
}
else if ( a->rank < b->rank )
{
return 1;
}
else
{
return ( a->rides < b->rides ) - ( b->rides < a->rides );
}
}
int main(void)
{
enum { N = 4 };
driver driver_list[N] =
{
{ "frank209", 3, 6 },
{ "john76", 7, 6 },
{ "harry99", 2, 2 },
{ "bob77", 5, 2 }
};
qsort( driver_list, N, sizeof( driver ), cmp );
for ( size_t i = 0; i < N; i++ )
{
printf( "%s, %u, %u\n",
driver_list[i].username, driver_list[i].rides, driver_list[i].rank );
}
return 0;
}
程序输出为
john76, 7, 6
frank209, 3, 6
bob77, 5, 2
harry99, 2, 2
这里的一个关键概念是记录“先于”另一个记录意味着什么。与其将其视为排序算法的一个特征(排序的结构如何才能按多个字段排序),不如将其视为记录之间关系的一个特征。您将只有一个常规排序算法,但其排序顺序“较早”的标准使用记录的两个字段。如果一个记录有更高的排名,或者如果排名相同,那么如果它有更多的游乐设施,则确定该记录在另一个之前。
一旦你知道“之前”的意思,你就有了排序关系。然后任何排序方法都可以。您只需使用选定的顺序进行排序。
如果您使用的是 C 标准 qsort
,您将编写一个比较函数:
- 接受指向
const void
的指针,这是必需的,因为 qsort
接口。
- 将这些指针转换为指向您的结构的指针。
- 如果第一个结构的等级高于第二个,return 负值(表示“更早”)。如果排名较低,return 正值(“稍后”)
- 否则,排名相等。如果第一个结构有更多游乐设施,return 为负值。如果它更少,return 肯定。如果它们相同,return 零。
如果您自己编写排序,您仍然使用上面的比较过程。
我必须编写一个函数来对数组中的结构进行排序。结构是:
#define MAX_USERNAME_LENGTH 16
typedef struct{
char username[MAX_USERNAME_LENGTH];
unsigned int rides;
unsigned int rank;
} driver;
程序从 .txt 文件加载数据并填充数组
driver driver_list[256]
我必须 driver_list 按等级和乘车次数排序。所以如果我的文件包含
//user rides rank
frank209 3 6
john76 7 6
harry99 2 2
bob77 5 2
输出必须显示:
john76 7 6
frank209 3 6
bob77 5 2
harry99 2 2
有办法吗?我已经尝试使用 2 个嵌套的选择排序,但在输出中我看到列表仅按等级或游乐设施排序。 感谢帮助
使用在header<stdlib.h>
中声明的标准函数qsort
并写一个user-defined比较函数。
给你。
#include <stdio.h>
#include <stdlib.h>
#define MAX_USERNAME_LENGTH 10
typedef struct
{
char username[MAX_USERNAME_LENGTH];
unsigned int rides;
unsigned int rank;
} driver;
int cmp( const void *left, const void *right )
{
const driver *a = ( const driver *)left;
const driver *b = ( const driver *)right;
if ( b->rank < a->rank )
{
return -1;
}
else if ( a->rank < b->rank )
{
return 1;
}
else
{
return ( a->rides < b->rides ) - ( b->rides < a->rides );
}
}
int main(void)
{
enum { N = 4 };
driver driver_list[N] =
{
{ "frank209", 3, 6 },
{ "john76", 7, 6 },
{ "harry99", 2, 2 },
{ "bob77", 5, 2 }
};
qsort( driver_list, N, sizeof( driver ), cmp );
for ( size_t i = 0; i < N; i++ )
{
printf( "%s, %u, %u\n",
driver_list[i].username, driver_list[i].rides, driver_list[i].rank );
}
return 0;
}
程序输出为
john76, 7, 6
frank209, 3, 6
bob77, 5, 2
harry99, 2, 2
这里的一个关键概念是记录“先于”另一个记录意味着什么。与其将其视为排序算法的一个特征(排序的结构如何才能按多个字段排序),不如将其视为记录之间关系的一个特征。您将只有一个常规排序算法,但其排序顺序“较早”的标准使用记录的两个字段。如果一个记录有更高的排名,或者如果排名相同,那么如果它有更多的游乐设施,则确定该记录在另一个之前。
一旦你知道“之前”的意思,你就有了排序关系。然后任何排序方法都可以。您只需使用选定的顺序进行排序。
如果您使用的是 C 标准 qsort
,您将编写一个比较函数:
- 接受指向
const void
的指针,这是必需的,因为qsort
接口。 - 将这些指针转换为指向您的结构的指针。
- 如果第一个结构的等级高于第二个,return 负值(表示“更早”)。如果排名较低,return 正值(“稍后”)
- 否则,排名相等。如果第一个结构有更多游乐设施,return 为负值。如果它更少,return 肯定。如果它们相同,return 零。
如果您自己编写排序,您仍然使用上面的比较过程。