如何使stl :: map键不区分大小写

San*_*ahu 12 c++ map

我是stl的新手.这是我的下面的程序.

typedef pair<string, int> p;
int main(int argc, char *argv[])
{
  map<string,int> st;
  st.insert(p("hello",1));   //Inserted "hello" as key to map.
  st.insert(p("HELLO",1));   //Inserted "HELLO" as key to map. 
  cout<<"size="<<st.size()<<endl;    //Output is 2 because two records found "hello" and "HELLO"
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我不想考虑重复的案例变化(大写字母为小写字母,反之亦然).这里"st.insert(p("HELLO",1));" 应该失败,因此没有.记录应为"1"而不是"2".是否有任何标志设置或类似的?

我无法找到相关问题因此发布了这个问题.

任何帮助都很感激.

P0W*_*P0W 30

使用自定义比较器:

struct comp { 
    bool operator() (const std::string& lhs, const std::string& rhs) const {
        return stricmp(lhs.c_str(), rhs.c_str()) < 0;
    }
};

std::map<std::string, int, comp> st;
Run Code Online (Sandbox Code Playgroud)

编辑: 如果您无法使用stricmp或strcasecmp使用:

#include<algorithm>
//...
string tolower(string s) {
    std::transform(s.begin(), s.end(), s.begin(), ::tolower );
    return s;
}
struct comp { 
    bool operator() (const std::string& lhs, const std::string& rhs) const {
        return  tolower(lhs) < tolower(rhs);
    }
};

std::map<std::string, int, comp> st;
Run Code Online (Sandbox Code Playgroud)

  • 我不建议使用第二个选项(使用`tolower`函数),因为它会创建一个新字符串.这意味着每个比较运算符有几个`new`和`delete`s.这将极大地减慢你的速度.此外,它将比较从"O(1)"平均(大多数字符串在第一个字符中不同)转换为"O(s)",其中s是字符串的平均大小.因此,不是单个字符比较,而是获得2`new`,2`删除`,2xs`fower` ... no. (6认同)
  • @TechnikEmpire 该映射基于“小于”比较:默认比较器是 `std::less` 谓词。这里通过检查 `stricmp(lhs, rhs)` 是否小于 0 来实现相同的行为。 (2认同)