Reputation: 2945
I have a vector < pair <double, int> >
, where double
represents weight of a person and int
represents the id of that person.
Now I need to convert it to set < pair < double, int > >
to remove the duplicates based on the id
of that person, but inside the vector I have data with some loose precision.
Example data:
-----------------------
double | int
-----------------------
10.234 | 1 <--
20.123 | 2
10.2 | 1 <--
30.33 | 3
As we can see, id 1
has weights in different precision.
Using the default comparator of std::set
will result in having 4 elements in the set, but I need only 3.
Only 1 element with id 1
should be there in the set (anyone from the two competitors will do).
The reason I'm not using std::map
is, because I need the entries to be in a specific sequence: I need them to be ordered by weight. For this reason, I'm using the following comparator:
struct comp__f {
bool operator() (const pair<double, int>& lhs, const pair<double, int>& rhs) const{
if(lhs.first < rhs.first) return true;
if(lhs.first > rhs.first) return false;
return lhs.second > rhs.second;
}
};
Note: The question is still open, @Robᵩ's answer doesn't solve the problem entirely, but I appreciate his effort.
Upvotes: 0
Views: 6302
Reputation: 9743
I know, I'm late to the party, but I had a similar problem and I think I solved it. Robᵩ was already on the right track, but your original lines need to be modified, too. All in all, I came up with the following comparator:
struct comp__f {
bool operator() (const pair<double, int>& lhs, const pair<double, int>& rhs) const {
return (lhs.second != rhs.second) && (lhs.first < rhs.first),
}
};
As Robᵩ explained, the (lhs.second != rhs.second)
part makes sure, that the IDs are unique. If this is guaranteed, then you just need to compare the weights using <
. So, (lhs.first < rhs.first)
ensures that the unique entries in the set get ordered by their weights.
Upvotes: 0
Reputation: 1035
Try this out
#include<set>
#include<iostream>
using namespace std;
class CustomComparitor
{
public:
int operator()(const pair<double,int>& lhs, const pair<double,int>& rhs)
{
return lhs.second < rhs.second;
}
};
int main()
{
set<pair<double,int>,CustomComparitor> myset;
myset.insert(make_pair(1.4, 2));
myset.insert(make_pair(1.5, 2));
myset.insert(make_pair(1.6, 1));
myset.insert(make_pair(1.4, 3));
for(auto itr = myset.begin(); itr!=myset.end();itr++)
{
cout<<itr->first<<" "<<itr->second<<endl;
}
return 0;
}
Upvotes: 0
Reputation: 168616
Since a record cannot be less than itself, or its equivalent self, ensure that your comp function returns false if two records have the same ID, regardless of weight.
// Assuming that your previous comp_f was correct, here is the new one:
struct comp__f {
bool operator() (const pair<double, int>& lhs, const pair<double, int>& rhs) const{
if(lhs.second == rhs.second) return false; // ADD THIS LINE
if(lhs.first < rhs.first) return true;
if(lhs.first > rhs.first) return false;
return lhs.second > rhs.second;
}
};
Upvotes: 4