Нечувствительный к регистру std:: набор строк
Как у вас есть нечувствительная к регистру вставка или поиск строки в std:: set?
Например -
std::set<std::string> s;
s.insert("Hello");
s.insert("HELLO"); //not allowed, string already exists.
Ответы
Ответ 1
Вам нужно определить пользовательский компаратор:
struct InsensitiveCompare {
bool operator() (const std::string& a, const std::string& b) const {
return stricmp(a.c_str(), b.c_str()) < 0;
}
};
std::set<std::string, InsensitiveCompare> s;
Ответ 2
std:: set предлагает возможность предоставления собственного сравнения (как и большинство контейнеров std). Затем вы можете выполнить любой тип сравнения, который вам нравится. Полный пример доступен здесь
Ответ 3
Из того, что я прочитал, это более переносимо, чем stricmp(), потому что stricmp() на самом деле не является частью библиотеки std, но реализована только большинством поставщиков компиляторов. В результате ниже мое решение просто сворачивать.
#include <string>
#include <cctype>
#include <iostream>
#include <set>
struct caseInsensitiveLess
{
bool operator()(const std::string& x, const std::string& y)
{
unsigned int xs ( x.size() );
unsigned int ys ( y.size() );
unsigned int bound ( 0 );
if ( xs < ys )
bound = xs;
else
bound = ys;
{
unsigned int i = 0;
for (auto it1 = x.begin(), it2 = y.begin(); i < bound; ++i, ++it1, ++it2)
{
if (tolower(*it1) < tolower(*it2))
return true;
if (tolower(*it2) < tolower(*it1))
return false;
}
}
return false;
}
};
int main()
{
std::set<std::string, caseInsensitiveLess> ss1;
std::set<std::string> ss2;
ss1.insert("This is the first string");
ss1.insert("THIS IS THE FIRST STRING");
ss1.insert("THIS IS THE SECOND STRING");
ss1.insert("This IS THE SECOND STRING");
ss1.insert("This IS THE Third");
ss2.insert("this is the first string");
ss2.insert("this is the first string");
ss2.insert("this is the second string");
ss2.insert("this is the second string");
ss2.insert("this is the third");
for ( auto& i: ss1 )
std::cout << i << std::endl;
std::cout << std::endl;
for ( auto& i: ss2 )
std::cout << i << std::endl;
}
Вывод с нечувствительным регистром и регулярным набором, показывающим тот же упорядочение:
This is the first string
THIS IS THE SECOND STRING
This IS THE Third
this is the first string
this is the second string
this is the third