I have to use quicksort to sort the states by percentage of population whose ages are equal or greater than 65 years old.
for (i = 0; i < n; i ) {
qsort(input_file, n, sizeof(int), sort_states);
}
CodePudding user response:
You have to define a comparison function for your struct:
int state_compare_by_age_65_or_gt(const void *s1, const void *s2)
{
const struct state *ss1 = s1;
const struct state *ss2 = s2;
if (ss1->ages_65_or_greater < ss2->ages_65_or_greater)
return -1;
else if (ss1->ages_65_or_greater > ss2->ages_65_or_greater)
return 1;
else
return 0;
}
And a function to print your states (for testing purposes, but you can use it for non-testing purposes as well):
void state_print(const struct state *st)
{
printf("%s\t%d\t%d\t%.2lf\t%.2lf\t%.2lf",
st->state_name,
st->population_2020,
st->population_2010,
st->ages_under_5,
st->ages_under_18,
st->ages_65_or_greater
);
}
Now you can use it with qsort()
:
int main(void)
{
struct state states[] = {
{"state1", 100, 200, 2.0, 3.0, 13.0},
{"state2", 100, 200, 2.0, 4.0, 10.0},
{"state3", 100, 200, 2.0, 5.0, 12.0},
{"state4", 100, 200, 2.0, 6.0, 11.0},
{"state5", 100, 200, 2.0, 7.0, 36.0},
{"state6", 100, 200, 10.0, 8.0, 140.0},
};
qsort(states, 6, sizeof(struct state), state_compare_by_age_65_or_gt);
for (int i = 0; i < 6; i ) {
state_print(&states[i]);
puts("");
}
}
Output:
state2 100 200 2.00 4.00 10.00
state4 100 200 2.00 6.00 11.00
state3 100 200 2.00 5.00 12.00
state1 100 200 2.00 3.00 13.00
state5 100 200 2.00 7.00 36.00
state6 100 200 10.00 8.00 140.00
CodePudding user response:
Alternatively, you can use array of structure pointers for optimal sorting.
- Input file (borrowing from above answer)
state1, 111, 211, 2.0, 3.0, 13.0
state2, 222, 322, 2.0, 4.0, 10.0
state3, 333, 433, 2.0, 5.0, 12.0
state4, 444, 544, 2.0, 6.0, 11.0
state5, 555, 655, 2.0, 7.0, 36.0
state6, 666, 755, 10.0, 8.0, 140.0
qsort
using structure pointers:
#include <stdio.h>
#include <stdlib.h>
#define str(x) # x
#define xstr(x) str(x)
#define MAX_NAME_LEN 127
typedef struct {
char name [MAX_NAME_LEN 1];
int pop_2020;
int pop_2010;
double age_lt5; // less than 5
double age_lt18;
double age_gte65; // greater or equal
} state_dtls;
int qsort_cmp (const void *p, const void *q) {
state_dtls *x = *(state_dtls **) p;
state_dtls *y = *(state_dtls **) q;
return (x->age_gte65 < y->age_gte65);
}
#define RECORD_STEP_SZ 2
int main() {
char in_file[MAX_NAME_LEN 1]; /* intializing the variables */
char out_file[MAX_NAME_LEN 1];
printf ("Enter Input file name: ");
scanf (" %" xstr(MAX_NAME_LEN) "s", in_file);
printf ("Enter Output file name: ");
scanf (" %" xstr(MAX_NAME_LEN) "s", out_file);
FILE *ipFile = fopen (in_file, "r");
if (!ipFile) {
perror ("Error Opening Input File"); return 1;
}
int rec_step = 0;
state_dtls** SPA = malloc (sizeof (state_dtls*) * RECORD_STEP_SZ * ( rec_step)); // state-details pointers array
if (!SPA) {
perror ("Error malloc SPA"); return 3;
}
int records = 0;
for (int ri = 0; 1; ri) {
state_dtls* sd = malloc (sizeof (state_dtls));
if (!sd) {
perror ("Error malloc state-dtls"); return 4;
}
if ((rec_step * RECORD_STEP_SZ) == ri) { // need more space for pointers
SPA = realloc (SPA, sizeof (state_dtls*) * RECORD_STEP_SZ * ( rec_step));
if (!SPA) {
perror ("Error malloc SPA2"); return 5;
}
}
if (6 != fscanf (ipFile, "%[^,], %d, %d, %lf, %lf, %lf\n",
sd->name, &sd->pop_2020, &sd->pop_2010,
&sd->age_lt5, &sd->age_lt18, &sd->age_gte65)) {
printf ("Error reading record [%d]\n", ri 1);
records = ri;
free (sd);
break; // break the loop // EOF
}
SPA[ri] = sd;
}
fclose (ipFile);
qsort (SPA, records, sizeof (state_dtls*), qsort_cmp);
// write to output file
FILE *opFile = fopen (out_file, "w");
if (!opFile) {
perror ("Error Opening output File"); return 2;
}
for (int ri = 0; ri < records; ri) {
fprintf (opFile, "%s, %d, %d, %lf, %lf, %lf\n",
SPA[ri]->name, SPA[ri]->pop_2020, SPA[ri]->pop_2010,
SPA[ri]->age_lt5, SPA[ri]->age_lt18, SPA[ri]->age_gte65);
free (SPA[ri]); // free memory resources as well
}
free (SPA);
fclose (opFile);
return 0;
}
- Output file with descending
age_gte65
parameter:
state6, 666, 755, 10.000000, 8.000000, 140.000000
state5, 555, 655, 2.000000, 7.000000, 36.000000
state1, 111, 211, 2.000000, 3.000000, 13.000000
state3, 333, 433, 2.000000, 5.000000, 12.000000
state4, 444, 544, 2.000000, 6.000000, 11.000000
state2, 222, 322, 2.000000, 4.000000, 10.000000