Reputation: 19
So, i want to sort a map<string, vector<int>>
by value in this kind of algorithm. There are 3 integers in the vector and i want to sort the map by the third value in the vector in the map in descending. If the third value is the same, sort by the second value descending, if the second value is the same then the first value.
Basically it goes like this:
P0001 10 100 100
P0002 0 0 200
P0003 1 100 100
After sorting:
P0002 0 0 200
P0001 10 100 100
P0003 1 100 100
My code:
#include <bits/stdc++.h>
using namespace std;
struct comp {
template <typename T>
// Comparator function
bool operator()(const T& l,
const T& r) const
{
if(l.second[2] != r.second[2]){
return l.second > r.second;
}
else{
if(l.second[1] != r.second[1]){
return l.second > r.second;
}
else{
if(l.second[0] != r.second[0]){
return l.second > r.second;
}
}
}
}
};
void sort(map<string, vector<int>>& M)
{
set<pair<string, vector<int>>, comp> S(M.begin(), M.end());
for (auto& it : S) {
cout << '\t' << it.first << '\t';
for (int i = 0; i < 3; i++)
{
cout << it.second[i] << "\t";
}
cout << endl;
}
}
int main(){
int Q, N, input;
string masuk, inputkey;
map<string, vector<int>> peserta;
vector<int> inputval;
cin >> Q >> N >> masuk;
for (int i = 0; i < Q; i++)
{
cin >> inputkey;
for (int i = 0; i < 3; i++)
{
cin >> input;
inputval.push_back(input);
}
peserta.insert(pair<string, vector<int>>(inputkey, inputval));
inputval.clear();
}
sort(peserta);
return 0;
}
I have read
https://www.geeksforgeeks.org/sorting-a-map-by-value-in-c-stl/
https://www.geeksforgeeks.org/map-of-vectors-in-c-stl-with-examples/
map of vectors in STL?
So far the inserting of the value works, only the sorting gone wrong.
Upvotes: 0
Views: 693
Reputation: 14392
As already said in another answer, a map is only sorted by its key.
If you don't use boost and you only need the alternative sorting temporarily, you can get away with an extra map std::multi_map<int, std::map<string, vector<int>>::iterator>
where you put all iterators to elements, based on a new key (third value in vector). Mind you, this new map is only valid as long as the original map doesn't change. If this is not good enough, you need to put the two map in an extra class to do the bookkeeping and so you're making a Boost.MultiIndex
.
Upvotes: 0
Reputation: 156
You can't sort a map like that, because it sorts its keys automatically and doesn't allow you to break order. What you can do is create a wrapper class around your string and vector, define a custom comparison operator for it and use std::set instead. You won't be able to get elements by their keys, though. If you want both getting by key and sorting, you may read about Boost.MultiIndex, or combine multiple containers for your task.
Upvotes: 3