【问题标题】:Is there a way to sort structs by multiple variables in C?有没有办法通过 C 中的多个变量对结构进行排序?
【发布时间】:2019-12-29 11:04:28
【问题描述】:

我必须编写一个对数组中的结构进行排序的函数。结构是:

#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 嵌套的选择排序,但在输出中我看到列表仅按排名或游乐设施排序。 感谢您的帮助

【问题讨论】:

  • 在标准 C 文档中查找 qsort 或 google。许多实现都提供了这个功能。
  • 简短回答:是的。通常的方法是有一个更高级的比较功能。您进行常规排序,但每次比较两条记录时,首先比较主键,如果它们相等,则回退并比较辅助键。
  • 您只需要根据 2 个值对排序进行比较即可。首先比较排名。如果它们不同,请采取相应措施。如果它们相同,请比较游乐设施并采取相应措施。

标签: c sorting struct structure qsort


【解决方案1】:

这里的一个关键概念是记录“先于”另一个记录意味着什么。与其将其视为排序算法的一个特征(排序是如何结构化以便按多个字段进行排序的),不如将其视为记录之间关系的一个特征。您将只有一个常规的排序算法,但其排序顺序中“较早”的标准使用记录的两个字段。如果一个记录具有更高的排名,或者如果排名相同,那么如果它有更多的游乐设施,则确定它在另一个记录之前。

一旦您知道“之前”的含义,您就有了排序关系。然后任何排序方法都可以。您只需使用选择的顺序进行排序。

如果您使用 C 标准 qsort,您将编写一个比较函数:

  • 获取指向const void 的指针,这是必需的,因为qsort 接口。
  • 将这些指针转换为指向您的结构的指针。
  • 如果第一个结构的排名大于第二个,则返回负值(表示“更早”)。如果排名较低,则返回正值(“稍后”)
  • 否则,排名相等。如果第一个结构有更多游乐设施,则返回负值。如果它更少,则返回正数。如果它们相同,则返回零。

如果您正在编写自己的排序,您仍然使用上面的比较过程。

【讨论】:

    【解决方案2】:

    使用标头<stdlib.h>中声明的标准函数qsort,编写用户自定义的比较函数。

    你来了。

    #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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-16
      • 1970-01-01
      • 2013-12-07
      • 1970-01-01
      • 2020-03-16
      • 2011-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多