一个STL菜鸟最常问的问题是“我怎么使用STL来进行忽略大小写的字符串比较?",这里用mismatch和lexicographical_compare两种方法实现。
首先是mismatch:返回两个范围中第一个不同的位置。代码如下:
int ciCharCompare(char c1, char c2)
// 忽略大小写比较字符 类似strcmp(返回一个负数、零或正数)
{
int Ic1 = tolower(static_cast<unsigned char>(c1));
int Ic2 = tolower(static_cast<unsigned char>(c2));
if (Ic1 < Ic2)
return -1;
if (Ic1 > Ic2)
return 1;
return 0;
}
int ciStringCompareImpl(const string& s1, const string& s2)
{
typedef pair<string::const_iterator,string::const_iterator> PSCI;
//找到第一个忽视大小写仍不等的字符 ciCharCompare与布尔值的相等正好相反 用not2处理
PSCI p = mismatch(s1.begin(), s1.end(), s2.begin(), not2(ptr_fun(ciCharCompare)));
if (p.first == s1.end())
{
if (p.second == s2.end())
return 0;
else
return -1;
}
return ciCharCompare(*p.first, *p.second);
}
int ciStringCompare(const string& s1, const string& s2)
//短的字符串在前
{
if (s1.size() <= s2.size())
return ciStringCompareImpl(s1, s2);
else
return -ciStringCompareImpl(s2, s1);
}
lexicographical_compare相当于strcmp的泛型版本。strcmp只对字符数组起作用,lexicographical_compare对所有任何类型值的区间都起作用,并且可以传入自定义比较函数。实现:
bool ciCharLess(char c1, char c2)
{
return tolower(static_cast<unsigned char>(c1)) < tolower(static_cast<unsigned char>(c2));
}
bool ciStringCompare(const string& s1, const string& s2)
//忽略大小写后字符串是否相等
{
return lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end(), ciCharLess);
}
另外,非标准库中可能有类似stricmp/strcmpi的忽略大小写的字符串比较函数,他们对长字符串运行起来一般比通用的算法mismatch和lexicographical_compare快得多。