问题
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 theqsort
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