Sort whole records, not just numbers.
What to build
A sort of an array of structs with two rules.
Requirements
- Read each student's name and CGPA.
- Sort them by CGPA from high to low. Equal CGPAs go in alphabetical order of name.
- Write the sort yourself. Print each student as
NAME CGPA, with two decimals.
Input
The first line has n. Each of the next n lines has a name and a CGPA.
Output
n lines.
Constraints
n is from 1 to 50. Names have at most 20 letters.
Example
Input:
3
Rahim 3.40
Nadia 3.90
Karim 3.60
Output:
Nadia 3.90
Karim 3.60
Rahim 3.40
Why it works
Because a struct can be assigned as a unit, swapping moves the name and the CGPA together, so the two can never get out of step.
Examples
Example 1 · Input
3 Rahim 3.40 Nadia 3.90 Karim 3.60
Expected output
Nadia 3.90 Karim 3.60 Rahim 3.40
Example 2 · Input
1 Mitu 4.00
Expected output
Mitu 4.00
Hints
Hint 1
Write a compare rule first: higher CGPA first, then name.
Hint 2
strcmp compares two names.
Hint 3
Assigning a struct copies all of it, so swapping two students takes three lines.
Solution
Show one correct solution (try it yourself first)
#include <stdio.h>
#include <string.h>
typedef struct {
char name[21];
double cgpa;
} Student;
int comes_after(const Student *a, const Student *b) {
if (a->cgpa != b->cgpa) {
return a->cgpa < b->cgpa;
}
return strcmp(a->name, b->name) > 0;
}
int main(void) {
int n;
Student s[50];
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%20s %lf", s[i].name, &s[i].cgpa);
}
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - 1 - i; j++) {
if (comes_after(&s[j], &s[j + 1])) {
Student temp = s[j];
s[j] = s[j + 1];
s[j + 1] = temp;
}
}
}
for (int i = 0; i < n; i++) {
printf("%s %.2f\n", s[i].name, s[i].cgpa);
}
return 0;
}