Sorting an array by multiple factors

Hello, I was trying to see if anyone can take a look at my code(I apologize in advanced if my title is misleading in any way - been a very long night). I am trying to have the output show the countries sorted by population and population density. I currently am able to sort by country name, this works just fine. I had some help elsewhere before, but now I am stuck again:

 ``123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171`` ``````#include #include #include #include using namespace std; class Country { public: Country(); // Parameterized constructor Country(char name[], int population, int area); // setters and getters char* getName(); int getPopulation(); int getArea(); void setName(char name[]); void setPopulation(int population); void setArea(int area); private: // Declaring variables // Declaring instance variables char name[30]; int population; int area; }; Country::Country() { } // Parameterized constructor Country::Country(char n[], int population, int area) { strcpy_s(name, n); this->population = population; this->area = area; } // setters and getters char* Country::getName() { return name; } int Country::getPopulation() { return population; } int Country::getArea() { return area; } void Country::setName(char n[]) { strcpy_s(name, n); } void Country::setPopulation(int population) { this->population = population; } void Country::setArea(int area) { this->area = area; } void sortByPopulation(Country counrties[], int SIZE); void sortByPopulationDensity(Country counrties[], int SIZE); void sortByName(Country counrties[], int SIZE); void display(Country countries[], int SIZE); int main() { //Declaring variables const int SIZE = 5; char name1[30] = { "England" }; char name2[30] = { "Scotland" }; char name3[30] = { "Ireland" }; char name4[30] = { "Portugal" }; char name5[30] = { "Belgium" }; Country countries[SIZE]; Country c1(name1, 55980000, 275); Country c2(name2, 5454000, 65); Country c3(name3, 4904000, 186); Country c4(name4, 10280000, 289); Country c5(name5, 11460000, 991); countries[0] = c5; countries[1] = c3; countries[2] = c4; countries[3] = c1; countries[4] = c2; sortByPopulation(countries, SIZE); cout << "_____________ After Sorting by Population _____________" << endl; display(countries, SIZE); sortByPopulationDensity(countries, SIZE); cout << "_____________ After Sorting by Population Density _____________" << endl; display(countries, SIZE); sortByName(countries, SIZE); cout << "_____________ After Sorting by name _____________" << endl; display(countries, SIZE); return 0; } void sortByPopulation(Country array[], int SIZE) { //This Logic will Sort the Array of elements in Ascending order Country temp; for (int i = 0; i < SIZE; i++) { for (int j = i + 1; j < SIZE; j++) { if (array[i].getPopulation() > array[j].getPopulation()) { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } } void sortByPopulationDensity(Country array[], int SIZE) { //This Logic will Sort the Array of elements in Ascending order Country temp; for (int i = 0; i < SIZE; i++) { for (int j = i + 1; j < SIZE; j++) { if ((array[i].getPopulation() / array[i].getArea()) > (array[j].getPopulation() / array[i].getArea())) { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } } void sortByName(Country array[], int SIZE) { //This Logic will Sort the Array of elements in Ascending order Country temp; for (int i = 0; i < SIZE; i++) { for (int j = i + 1; j < SIZE; j++) { if (strcmp(array[i].getName(), array[j].getName()) > 0) { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } } void display(Country countries[], int SIZE) { cout << setw(15) << left << "Name" << setw(15) << left << "Population " << setw(10) << left << "Area" << endl; cout << setw(15) << left << "----" << setw(15) << left << "---------- " << setw(10) << left << "----" << endl; for (int i = 0; i < SIZE; i++) { cout << setw(15) << left << countries[i].getName() << setw(15) << left << countries[i].getPopulation() << setw(10) << left << countries[i].getArea() << endl; } }``````

Appreciate anyone who has any input.
Last edited on
 ``123456789101112131415161718192021222324252627282930313233343536373839404142434445`` ``````#include #include #include #include #include struct country { std::string name; int population; int area; }; double population_density(country c) { return static_cast(c.population) / c.area; } void display(std::vector const& cs) { auto const& field_width = std::setw(20); std::cout << std::left; std::cout << field_width << "Name" << field_width << "Population" << field_width << "Area" << '\n'; for (country const& c: cs) std::cout << field_width << c.name << field_width << c.population << field_width << c.area << '\n'; } int main() { std::vector countries { {"England", 55980000, 275}, {"Scotland", 5454000, 65 }, {"Ireland", 4904000, 186}, {"Portugal", 10280000, 289}, {"Belgium", 11460000, 991} }; std::cout << "_____________ After Sorting by Population _____________\n"; std::sort(countries.begin(), countries.end(), [](country a, country b) { return a.population < b.population; }); display(countries); std::cout << "_____________ After Sorting by Population Density _____________\n"; std::sort(countries.begin(), countries.end(), [](country a, country b) { return population_density(a) < population_density(b); }); display(countries); std::cout << "_____________ After Sorting by name _____________\n"; std::sort(countries.begin(), countries.end(), [](country a, country b) { return a.name < b.name; }); display(countries); }``````
Please state what your actual problem is.

It appears to sort correctly by name and by population.

So look at the population density case: you write an i where there should be a j at the end of line 136.

Did you know that there are library routines for swap and sort?
 sorted by population and population density

Do you mean, once sorted by population, the countries with the highest population density should come before?
Most you have is worthy of keeping except for some re-shuffling and taking advantage of repetitive behavior, hence methods/functions.

The easily found index i,j =blooper is easily fixed.

std::<strings> are better than C-style strings (like stayin away from using namespace std nemesis - yawn - where have I heard that before)

Good on you for not taking the easy way out despite the <vector> patrol inspectors

getDensity() is a worthwhile method to simplify and add readability.

Your dataset, however genuine it is, should enable checking against what you are getting what you want. Fudge the data to enable testing, so that real data processing reliability can be demonstrated.

The sort by a plus b seems to be handled by the sequence sorting, mainly because the array changes to meet the immediate need. Maybe that's good, maybe not if you ever want to get back to the unsorted dataset.

 ``123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163`` ``````#include #include #include #include using namespace std; class Country { private: char name[30]; int population; int area; public: Country(); Country(char* name, int population, int area); ~Country(){}; char* getName(); int getPopulation(); int getArea(); void setName(char name[]); void setPopulation(int population); void setArea(int area); void display(); double getDensity(); static void display_list(int SIZE, Country *countries) { for(int i = 0; i < SIZE; i++) countries[i].display(); } }; Country::Country(){} Country::Country(char n[], int population, int area) { strcpy(name, n); this->population = population; this->area = area; } char* Country::getName(){return name;} int Country::getPopulation(){return population; } int Country::getArea(){ return area;} void Country::setName(char n[]){strcpy(name, n);} void Country::setPopulation(int population){this->population = population;} void Country::setArea(int area){this->area = area;} double Country::getDensity(){return population/area;} void Country::display() { cout << setw(15) << left << name << setw(15) << left << population << setw(10) << left << area << setw(10) << left << getDensity() << '\n'; } void sortByPopulation(Country counrties[], int SIZE); void sortByPopulationDensity(Country counrties[], int SIZE); void sortByName(Country counrties[], int SIZE); int main() { const int SIZE = 7; Country countries[SIZE]; countries[0] = Country{"England" , 55980000, 275}; countries[1] = Country{"Scotland", 5454000, 65}; countries[2] = Country{"Ireland" , 4904000, 186}; countries[3] = Country{"Portugal", 10280000, 289}; countries[4] = Country{"Panama" , 11460000, 288}; countries[5] = Country{"Angola" , 20000000, 991}; countries[6] = Country{"Australia" , 20000000, 992}; cout << "UNSORTED\n"; Country::display_list(SIZE, countries); cout << "\n\n"; sortByPopulation(countries, SIZE); cout << "SORTED BY POPULATION (ASC)\n"; Country::display_list(SIZE, countries); cout << "\n\n"; sortByPopulationDensity(countries, SIZE); cout << "--SORTED BY POPULATION DENSITY (ASC)\n"; Country::display_list(SIZE, countries); cout << "\n\n"; sortByName(countries, SIZE); cout << "SORTED BY NAME (ASC)\n"; Country::display_list(SIZE, countries); cout << "\n\n"; sortByName(countries, SIZE); sortByPopulationDensity(countries, SIZE); cout << "SORTED BY NAME THEN DENSITY (ASC)\n"; Country::display_list(SIZE, countries); cout << "\n\n"; sortByPopulationDensity(countries, SIZE); sortByName(countries, SIZE); cout << "SORTED BY DENSITY THEN NAME (ASC)\n"; Country::display_list(SIZE, countries); cout << "\n\n"; return 0; } void sortByPopulation(Country array[], int SIZE) { // This Logic will Sort the Array of elements in Ascending order Country temp; for (int i = 0; i < SIZE; i++) { for (int j = i + 1; j < SIZE; j++) { if (array[i].getPopulation() > array[j].getPopulation()) { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } } void sortByPopulationDensity(Country array[], int SIZE) { // This Logic will Sort the Array of elements in Ascending order Country temp; for (int i = 0; i < SIZE; i++) { for (int j = i + 1; j < SIZE; j++) { if ( array[i].getDensity() > array[j].getDensity() ) // <-- { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } } void sortByName(Country array[], int SIZE) { // This Logic will Sort the Array of elements in Ascending order Country temp; for (int i = 0; i < SIZE; i++) { for (int j = i + 1; j < SIZE; j++) { if (strcmp(array[i].getName(), array[j].getName()) > 0) { temp = array[i]; array[i] = array[j]; array[j] = temp; } } } }``````

 ``` UNSORTED England 55980000 275 203563 Scotland 5454000 65 83907 Ireland 4904000 186 26365 Portugal 10280000 289 35570 Panama 11460000 288 39791 Angola 20000000 991 20181 Australia 20000000 992 20161 SORTED BY POPULATION (ASC) Ireland 4904000 186 26365 Scotland 5454000 65 83907 Portugal 10280000 289 35570 Panama 11460000 288 39791 Angola 20000000 991 20181 Australia 20000000 992 20161 England 55980000 275 203563 --SORTED BY POPULATION DENSITY (ASC) Australia 20000000 992 20161 Angola 20000000 991 20181 Ireland 4904000 186 26365 Portugal 10280000 289 35570 Panama 11460000 288 39791 Scotland 5454000 65 83907 England 55980000 275 203563 SORTED BY NAME (ASC) Angola 20000000 991 20181 Australia 20000000 992 20161 England 55980000 275 203563 Ireland 4904000 186 26365 Panama 11460000 288 39791 Portugal 10280000 289 35570 Scotland 5454000 65 83907 SORTED BY NAME THEN DENSITY (ASC) Australia 20000000 992 20161 Angola 20000000 991 20181 Ireland 4904000 186 26365 Portugal 10280000 289 35570 Panama 11460000 288 39791 Scotland 5454000 65 83907 England 55980000 275 203563 SORTED BY DENSITY THEN NAME (ASC) Angola 20000000 991 20181 Australia 20000000 992 20161 England 55980000 275 203563 Ireland 4904000 186 26365 Panama 11460000 288 39791 Portugal 10280000 289 35570 Scotland 5454000 65 83907 Program ended with exit code: 0 ```
Last edited on
@mbozzi this looks great and rather easier to read/comprehend! I ran your version and it did not sort by population density. I'm going to take a look to see if I can make an adjustment for it to sort by density. I appreciate the response.

@lastchance my code was not outputting a proper sort by population. My issue is the way my code outputs the proper sorting for countries by population and by population density. It outputs by name correctly. I only started C++ a month ago and have much to learn, I will have to look into and learn about library routines for swapping. Thank you for your input.

@enoizat correct, sorry for the vague question. the code properly creates a table for each; population, population density, and country name. The problem is, it would only sort by country name (A-Z) in all 3 tables and not population or population density.

@againtry I appreciate the coding compliment! Fairly new still and learning every day. I appreciate all these tips as well
@shawnphi,
I think you will find that @mbozzi's code IS correctly sorting by population density ... it's just that you aren't outputting that quantity to check.

As far as I can see, the only point where your code gives you the wrong answer is using an i when it should have been a j, and you have an integer division problem as well (note how @mbozzi casts to avoid this).

Your sorting technique does use an awful lot of swaps. You are also writing almost exactly the same code three times, which should send out a red flag.

If you didn't use strcpy_s, which is non-standard, we would be able to run your code in cpp.sh, the online compiler.
Last edited on
@lastchance ahh I see what you're saying. let me circle back to my original one and take a look at "i" and "j".
Last edited on
It doesn't affect the order here, but be careful about the integer division (and hence truncation) in calculating population density.
@shawnphi
I flagged the i,j problem in my post. It is in my line 137 which is your otherwise unchanged code for that function.

Keep in mind also that you could cut out at least one of the sorting functions and just have one for strings and one for numbers.

You can even reduce that to one only templated function if youâ€™re up to that.

swapping 2 array elements can be a useful function simplification too. Keeps it simple, aids readability and assists de-bugging

Registered users can post here. Sign in or register to post.