Как сделать stl:: 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;
}

Я не хочу принимать во внимание повторяющиеся изменения случая (верхний регистр для нижних слов или наоборот). Здесь "st.insert(p (" HELLO ", 1)); должен потерпеть неудачу, следовательно, нет. записей должно быть" 1 "вместо" 2". Есть ли какая-либо установка флага или так?

Я не смог найти связанные вопросы, поэтому разместил этот вопрос.

Любая помощь благодарна.

Ответ 1

Используйте собственный компаратор:

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;

Изменить: Если вы не можете использовать 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;

Ответ 2

Есть два способа сделать это

Сначала - измените функцию сравнения, чтобы игнорировать регистр

Вторые - всякий раз, когда вы используете строку для ввода или получения значения из карты, заверните ее с помощью функции, которая превращает ее в нижний регистр.

Для всего, что вам нужно сделать, это создать "класс функций" (класс с operator()), который получает две строки и возвращает ли "меньше" слева, чем правое:

struct my_comparitor{
  bool operator()(const std::string &a, const std::string &b){
    // return iwhether a<b
  }
};

std::map<std::string,DATA_TYPE,my_comparitor> my_map;

Для второго просто выполните следующее:

std::map<std::string,DATA_TYPE> my_map;
my_map.insert(std::make_pair(TO_LOWERCASE("hello"),1));
iter=my_map.find(TO_LOWERCASE(key));
cout << my_map[TO_LOWERCASE(name)];
// etc.

Я не уверен, что функция, которая преобразуется в нижний регистр, уже является частью stl - но в любом случае ее легко написать.