Home > Software design >  How to sort map by value in a Descending order? C
How to sort map by value in a Descending order? C

Time:11-14

So basically I found this piece of code that sorts map by value:

bool cmp(pair<string, int>& a,
         pair<string, int>& b)
{
    return a.second < b.second;
}
  
void sort(map<string, int>& M)
{
    vector<pair<string, int> > A;
  
    for (auto& it : M) 
        A.push_back(it);
  
    sort(A.begin(), A.end(), cmp);
}

but it sorts map in an ascending order which I need to be in descending, how do I do it?

I thought that I could just iterate through map backwards but couldn't because of mine lack of knowledge.

CodePudding user response:

Change < in the return of the cmp function to > if you want to sort in descending order. What you are doing in your case is you sort in ascending order.

CodePudding user response:

First, a std::map is sorted. You can use the reverse iterator to follow it backwards.

#include <iostream>
#include <map>

int main(void) {

    std::map<std::string, int> your_map {
        {"a", 1},
        {"b", 2},
        {"c", 3}
    };


    for (auto it = your_map.rbegin(); it != your_map.rend();   it) {
        std::cout << it->first << ", " << it->second << std::endl;
    }

    return 0;
}

Second, since it is already sorted, and you can reverse iterate the map, there is no reason to sort it again.

Third, you're using an iterator as your vector element type. You probably want the key, or value of the item in the map. The example below is using the element type. You can use other more advanced methods, but as it seems you're a beginner, the method below might be easier to understand.

#include <iostream>
#include <map>
#include <vector>

int main(void) {

    std::map<std::string, int> your_map {
        {"a", 1},
        {"b", 2},
        {"c", 3}
    };

    std::vector<int> v;

    for (auto it = your_map.rbegin(); it != your_map.rend();   it) {
        v.push_back(it->second);
    }

    for (auto it = v.begin(); it != v.end();   it) {
        std::cout << *it << std::endl;
    }    

    return 0;
}

Last, you can use the std::less, and std::greater functional classes to get the result you're looking for as well that is applied to the key of the map.

#include <iostream>
#include <map>
#include <vector>
#include <functional>

int main(void) {

    std::map<std::string, int, std::greater<std::string>> your_map {
        {"a", 1},
        {"b", 2},
        {"c", 3}
    };

    std::vector<int> v;
    // notice the forward iterator below
    for (auto it = your_map.begin(); it != your_map.end();   it) {
        v.push_back(it->second);
    }
    // prints reversed order
    for (auto it = v.begin(); it != v.end();   it) {
        std::cout << *it << std::endl;
    }    

    return 0;
}
  • Related