Is there a way to sort structs by multiple variables in C?

﹥>﹥吖頭↗ 提交于 2021-02-10 05:44:06

问题


I have to write a function that sorts structs in an array. the struct is:

#define MAX_USERNAME_LENGTH 16

typedef struct{
 char username[MAX_USERNAME_LENGTH];
 unsigned int rides;
 unsigned int rank;
} driver;

The program load the data from a .txt file and fills an array

driver driver_list[256]

I have to sort driver_list by ranks AND number of rides. So if my file contains

//user rides rank
frank209 3 6
john76 7 6
harry99 2 2
bob77 5 2

Output must show:

john76 7 6
frank209 3 6
bob77 5 2
harry99 2 2

There's a way to do that? I've tried selection sort with 2 nested for, but in output i see the list sorted only by rank OR rides. Thanks for help


回答1:


Use the standard function qsort declared in the header <stdlib.h> and write a user-defined comparison function.

Here you are.

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

The program output is

john76, 7, 6
frank209, 3, 6
bob77, 5, 2
harry99, 2, 2



回答2:


A key concept here is what does it mean for a record to be “before” another. Rather than thinking of this as a feature of the sort algorithm—how is the sort structured so that it sorts by multiple fields—it is a feature of the relationship between records. You will have only a regular sort algorithm, but its criterion for what is “earlier” in sort order uses two fields of the record. A record is determined to be before another if it has a higher rank or, if the ranks are the same, then if it has more rides.

Once you know what “before” means, you have an ordering relationship. Then any sort method will do. You merely sort using the chosen ordering.

If you are using the C standard qsort, you will write a compare function that:

  • Takes to pointers to const void, which is necessary because of the qsort interface.
  • Converts those pointers to pointers to your structures.
  • If the first structure has rank greater than the second, return a negative value (to mean “earlier”). If it has lesser rank, return a positive value (“later”)
  • Otherwise, the ranks are equal. If the first structure has more rides, return a negative value. If it has fewer, return positive. If they are the same, return zero.

If you are writing your own sort, you still use the comparison procedure above.



来源:https://stackoverflow.com/questions/57637855/is-there-a-way-to-sort-structs-by-multiple-variables-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!