Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using comparator for STL set

Check the following code:

string toLowerCase(const string& str) {
    string res(str);
    int i;

    for (i = 0; i < (int) res.size(); i++)
        res[i] = (char) tolower(res[i]);

    return res;
}

class LeagueComparator
{
public:
    bool operator()(const string& s1, const string& s2)
    {
        return toLowerCase(s1) < toLowerCase(s2);
    }
};

int main()
{
    set<string, LeagueComparator> leagues;
    set<string, LeagueComparator>::iterator iter;

    leagues.insert("BLeague");
    leagues.insert("aLeague");    // leagues = {"aLeague", "BLeague"}
    leagues.insert("ALeague");

    for (iter = leagues.begin(); iter != leagues.end(); iter++)
        cout << *iter << endl;

    return 0;
}

The output is:

aLeague
BLeague

which is shocking to me. I thought (and expecting) the output would be:

aLeague
ALeague
BLeague

Before the execution of leagues.insert("ALeague");, the leagues contains "aLeague" and "BLeague". My question is, while executing leagues.insert("ALeague"); why the machine treats "ALeague" == "aleague"? According to my understanding, there is no element "ALeague" in leagues. So "ALeague" should be inserted into leagues. The comparator should determine where to put "ALeague".

Thanks in advance.

PS: Please don't hit me for using C style cast. :P I'm too lazy to type static_cast.

like image 392
Donotalo Avatar asked Oct 30 '10 05:10

Donotalo


People also ask

How do you use a custom comparator in a set?

auto cmp = [](int a, int b) { return ... }; std::set<int, decltype(cmp)> s; We use lambda function as comparator. As usual, comparator should return boolean value, indicating whether the element passed as first argument is considered to go before the second in the specific strict weak ordering it defines.

How do I use comparator in CPP?

The comparator class compares the student to be searched from the list of students on the basis of their name attribute. If the name attribute of the object to be searched is equal to any of the object's name attribute in the list then it returns true, otherwise, it returns false.

How does comparator function works in sorting?

If you compare age first and then compare name if the ages are equal, the sequence will be sorted by age -- but within each subsequence where the age is equal, that subsequence is sorted by name.

What is the comparator function?

The comparator function takes two arguments and contains logic to decide their relative order in sorted output. The idea is to provide flexibility so that qsort() can be used for any type (including user defined types) and can be used to obtain any desired order (increasing, decreasing or any other).


3 Answers

Your comparator, thanks to the toLowerCase, says that "aLeague" == "ALeague". Since (according to your comparator) "aLeague" < "ALeague" == false and "ALeague" < "aLeague" == false, they must be equivalent. And inserting an equivalent element into a set doesn't do anything.

like image 126
John Calsbeek Avatar answered Oct 03 '22 19:10

John Calsbeek


When you insert any value to a set, the object checks to see whether it already contains that value. Your LeagueComparator object compares ALeague with the other two values already in the set. It determines that the existing value aLeague is neither greater than nor less than the proposed new entry (ALeague), so they must be equal, and so it doesn't proceed with the insert. The set remains with just two elements. That's the whole point of providing a customer comparison object, so you can control how the set determines whether two elements match.

like image 45
Rob Kennedy Avatar answered Oct 03 '22 21:10

Rob Kennedy


Given the comparator you provided, "ALeague" is indeed equivalent "aLeague".

Given two values, x and y, and a less-than comparator z:

  • If z(x, y) is true, then x is less than y
  • If z(y, x) is true, then y is less than x
  • If neither is true, then x is equivalent to y
  • If both are true, then you have a broken comparator.
like image 34
Eclipse Avatar answered Oct 03 '22 21:10

Eclipse