使用比较器进行STL设置

发布于 2024-09-29 11:05:46 字数 1355 浏览 0 评论 0原文

检查以下代码:

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;
}

输出是:

aLeague
BLeague

这让我感到震惊。我认为(并期望)输出将是:

aLeague
ALeague
BLeague

在执行 leagues.insert("ALeague"); 之前,leagues 包含 "aLeague"和<代码>“BLeague”。我的问题是,在执行 leagues.insert("ALeague"); 时,为什么机器会处理 "ALeague" == "aleague"?据我了解,leagues中没有"ALeague"元素。所以“ALeague”应该插入到leagues中。比较器应确定在何处放置“ALeague”

提前致谢。

PS:请不要因为我使用C风格演员而打我。 :P 我懒得输入static_cast

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蓝天白云 2024-10-06 11:05:46

由于 toLowerCase,您的比较器表示 "aLeague" == "ALeague"。因为(根据您的比较器)"aLeague" < "ALeague" == false"ALeague" < "aLeague" == false,它们必须是等价的。将等效元素插入集合中不会执行任何操作。

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.

草莓味的萝莉 2024-10-06 11:05:46

当您向集合中插入任何值时,该对象会检查它是否已包含该值。您的 LeagueComparator 对象将 ALeague 与集合中已有的其他两个值进行比较。它确定现有值 aLeague 既不大于也不小于建议的新条目 (ALeague),因此它们必须相等,因此不会继续插入物。该集合仍然只有两个元素。这就是提供客户比较对象的全部意义,因此您可以控制集合如何确定两个元素是否匹配。

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.

冷︶言冷语的世界 2024-10-06 11:05:46

鉴于您提供的比较器,“ALeague”确实相当于“aLeague”。

给定两个值 x 和 y 以及小于比较器 z:

  • 如果 z(x, y) 为真,则 x 小于 y
  • 如果 z(y, x) 为真,则 y 小于 x
  • 如果两者都不是为真,则 x 等于 y
  • 如果两者都为真,则比较器损坏。

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.
贪恋 2024-10-06 11:05:46

将您的 LeagueComparator 替换为

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

Replace your LeagueComparator with

class LeagueComparator
{
public:
    bool operator()(const string& s1, const string& s2)
    {
        return toLowerCase(s1) < toLowerCase(s2)   ||  
               !(toLowerCase(s2) < toLowerCase(s1))  &&  s1 < s2;
    }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文