C++ 以不区分大小写的字母顺序打印地图

CGu*_*utz 4 c++ sorting map alphabetical c++11

我有一个:

map<string, map<int,int>>
Run Code Online (Sandbox Code Playgroud)

有没有办法按字母顺序打印此地图的内容,但不区分大小写?例如,按以下顺序打印:

A : 1:1, 2:2
a : 3:1
an : 2:1
And : 4:1
and : 3:1
Run Code Online (Sandbox Code Playgroud)

目前,我正在使用以下方法进行打印:

for (auto it = tokens.begin(); it != tokens.end(); ++it){
    cout << it->first << " : ";
    auto const &internal_map = it->second;
    for (auto it2 = internal_map.begin(); it2 != internal_map.end(); ++it2){
        if (it2 != internal_map.begin())
            cout << " , ";
        cout << it2->first << ":" << it2->second;
    }       
    cout << endl;
}
Run Code Online (Sandbox Code Playgroud)

这将打印所有内容,但是,它首先通过所有大写字母,然后是所有小写字母。例如:

A : 1:1, 2:2
And : 4:1
a : 3:1
an : 2:1
and : 3:1
Run Code Online (Sandbox Code Playgroud)

Mar*_*som 5

正如接受的答案中所述,您希望将 amap与自定义比较函数一起使用。诀窍是进行适当的比较。您不希望完全不区分大小写的比较或“And”和“and”会相等,只允许其中一个出现在地图中。您的样本数据并未涵盖所有情况;例如,“An”、“And”、“AN”、“AND”的顺序是什么?下面的比较函数将它们排序为“AN”、“An”、“AND”、“And”——较短的字符串总是小于相同字符的较长字符串,并且具有不同大小写的第一个字符是大写的决胜局-case 在小写之前。

struct CaseAwareCompare
{
    bool operator()(const char * left, const char * right) const
    {
        bool tied = true, tiebreaker = false;
        for (int i = 0; left[i] != 0; ++i)
        {
            if (right[i] == 0)
                return false;
            if (tolower(left[i]) != tolower(right[i]))
                return tolower(left[i]) < tolower(right[i]);
            if (tied && left[i] != right[i])
            {
                tied = false;
                tiebreaker = left[i] < right[i];
            }
        }
        return (right[i] != 0) || (!tied && tiebreaker);
    }

    bool operator()(const string & left, const string & right) const
    {
        return operator()(left.c_str(), right.c_str());
    }
};
Run Code Online (Sandbox Code Playgroud)

我挣扎着如何称呼它;它不是不区分大小写的比较,因为它区分不同大小写的输入。我最终决定将其称为案例感知比较。