2013-09-30 2 views
11

Я новичок в stl. Вот моя нижняя программа.как сделать stl :: map key case нечувствительный

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». Есть ли какая-либо установка флага или так?

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

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

+3

Простейший способ заключается в том, чтобы превратить их в нижний регистр перед добавлением на карту. – zch

ответ

26

Использование пользовательского компаратор:

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; 

Edit: Если вы не в состоянии использовать 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; 
+6

Я бы не рекомендовал второй вариант (с функцией 'tolower'), поскольку он создает новую строку. Это означает пару 'новых' и' delete 'для оператора сравнения. Который БОЛЬШОЕ замедлит вас. Также он сравнивает сравнение с «O (1)» в среднем (большинство строк отличается от первого символа) до «O (s)», где s - средний размер строки. Поэтому вместо одного сравнения символов вы получаете 2 'новых', 2' delete', 2xs 'tolower' ... no. – rabensky

+0

Можете ли вы объяснить, почему возврат <0, а не == 0? Я думал, что с функциями str *** cmp меньше нуля указывает, что левая сторона является подстрокой правой руки, где равное совпадение равно 0. –

+1

@TechnikEmpire. Карта основана на сравнении «меньше»: компаратор по умолчанию является предикатом 'std :: less'. Такое же поведение достигается здесь, проверяя, является ли 'stricmp (lhs, rhs)' меньше 0. –

2

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

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

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

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

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. 

Я не уверен, если это функция, которая переходит в нижний регистр уже является частью СТЛ - но в любом случае это легко писать.

Смежные вопросы