5

次のコードを確認してください。

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"ですか? 私の理解によると、 には要素がありませ"ALeague"leagues。に挿入"ALeague"する必要がありますleagues。コンパレータは、どこに配置するかを決定する必要があり"ALeague"ます。

前もって感謝します。

PS: C スタイルのキャストを使用しているからといって、私を殴らないでください。:P 私は入力するのが面倒ですstatic_cast

4

4 に答える 4

14

あなたのコンパレータは、 のおかげでtoLowerCase、 と言ってい"aLeague" == "ALeague"ます。(コンパレータによると)"aLeague" < "ALeague" == false"ALeague" < "aLeague" == falseであるため、それらは同等でなければなりません。同等の要素をセットに挿入しても何も起こりません。

于 2010-10-30T05:57:10.260 に答える
4

セットに値を挿入すると、オブジェクトはその値が既に含まれているかどうかを確認します。オブジェクトは、セット内に既にある他の 2 つの値LeagueComparatorと比較されます。ALeague既存の値aLeagueが提案された新しいエントリ ( ) よりも大きくも小さくもないALeagueため、それらは等しい必要があり、挿入を続行しません。セットには 2 つの要素だけが残ります。これが顧客比較オブジェクトを提供する要点であり、2 つの要素が一致するかどうかをセットがどのように判断するかを制御できます。

于 2010-10-30T05:58:04.567 に答える
3

あなたが提供したコンパレータを考えると、「ALeague」は実際に「aLeague」と同等です。

x と y の 2 つの値と、小なりコンパレータ z を指定すると、次のようになります。

  • z(x, y) が true の場合、x は y より小さい
  • z(y, x) が true の場合、y は x より小さい
  • どちらも真でない場合、x は y に等しい
  • 両方とも true の場合、コンパレータが壊れています。
于 2010-10-30T05:56:59.427 に答える
0

LeagueComparatorに置き換えます

class LeagueComparator
{
public:
    bool operator()(const string& s1, const string& s2)
    {
        return toLowerCase(s1) < toLowerCase(s2)   ||  
               !(toLowerCase(s2) < toLowerCase(s1))  &&  s1 < s2;
    }
};
于 2010-10-30T07:04:55.577 に答える