Daryl Drake
Daryl Drake

Reputation: 29

Ordering a set of pairs in decending order by the first value and then alphabetically by the second value

I have a set of pairs of integers and sets, e.g: items = {(2,{"A", "B", "C"}),(3,{"C"}),...}
I have it set up this way because stl sets can be easily ordered by writing a comparator for the declaration, I do not know how to write such a function to do what I need however. I need to print out in descending order based on the integer value (the first value of the pair), and if two items share an integer value then alphabetically by the string. Currently it prints out in ascending order by integer value and alphabetically by string. I will attach expected and current outputs below.

set<pair<int, set<string>>> outputSet;
map<set<string>, int> supportMap;
set<set<string>> candidateItemSets;
vector<set<set<string>>> frequentItemSets;

for(int i = 0; i < frequentItemSets.size(); i++){
    for(auto it = frequentItemSets[i].begin(); it != frequentItemSets[i].end(); it++){
        pair<int, set<string>> temp(supportMap[*it],*it);
        outputSet.insert(temp);
    }
}

for(auto it = outputSet.begin(); it != outputSet.end(); it++){
    pair<int, set<string>> temp = *it;

    auto sit = temp.second.begin();
    auto end = temp.second.end();
    advance(end, -1);

    cout << temp.first << " [";
    for(sit; sit != end; sit++)
        cout << *sit << " ";

    cout << *sit << "]" << endl;

/**
current output:  
2 [A]  
2 [A C]  
2 [B]  
2 [B C]  
2 [B C D]  
2 [B D]  
2 [C D]  
2 [D]  
3 [C]  

expected output:  
3 [C]  
2 [A]  
2 [A C]  
2 [B]  
2 [B C]  
2 [B C D]  
2 [B D]  
2 [C D]  
2 [D]
**/

Upvotes: 2

Views: 2299

Answers (1)

mksteve
mksteve

Reputation: 13073

In general, if you want to store items, and have specific rules about ordering, you would write a comparison routine, which would ensure the ordering was what you wanted.

std::set< type, comparator > Where comparator has a function object

The following comparitor would reverse the number test, so the ordering was what you wanted originally.

bool operator()(const std::pair< std::string, int> &lhs, const std::pair<std::string, int> &rhs) const 
{
    if( lhs.first < rhs.first ) // string ordering is already correct
        return true;
    if( lhs.first > rhs.first ) 
        return false;  // needed to ensure we don't test second.
    if( lhs.second > rhs.second )
        return true;
    return false;
}

Upvotes: 1

Related Questions