#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
struct lt_noCase :
public binary_function<char, char, bool>{
bool operator()(const char& a, const char&b)
{
return toupper(static_cast<unsigned char>(a)) <
toupper(static_cast<unsigned char>(b));
}
};
int main()
{
//string x("hahah");
//string y("babab");
//bool answer = lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
const char* s1 = "GEW\334RZTRAMINER";
const char* s2 = "gew\373rztraminer";
printf("s1<s2:%s\n",
(lexicographical_compare(s1, s1 + 14, s2, s2 + 14, lt_noCase()) ? "true" : "false"));
//cout << "s1<s2:" <<
// (lexicographical_compare(s1, s1 + 14, s2, s2 + 14, lt_noCase()) ? "true" : "false") << endl;
//结果为true
}
加上一句话setlocale(LC_ALL,”de”),这告诉C库,将使用德语的习惯来进行,因为德语中包含字符(u上加两点),因此s1=s2,所以结果为false,如果不加的话,默认是使用简单的英语文本,所以上边的结果是对的。
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
struct lt_noCase :
public binary_function<char, char, bool>{
bool operator()(const char& a, const char&b)
{
return toupper(static_cast<unsigned char>(a)) <
toupper(static_cast<unsigned char>(b));
}
};
int main()
{
//string x("hahah");
//string y("babab");
//bool answer = lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
const char* s1 = "GEW\334RZTRAMINER";
const char* s2 = "gew\373rztraminer";
setlocale(LC_ALL, "de");
printf("s1<s2:%s\n",
(lexicographical_compare(s1, s1 + 14, s2, s2 + 14, lt_noCase()) ? "true" : "false"));
//cout << "s1<s2:" <<
// (lexicographical_compare(s1, s1 + 14, s2, s2 + 14, lt_noCase()) ? "true" : "false") << endl;
//结果为false
}
接下来是其使用方法实例:
locale l("de");//设置l为德语
//下边的代码将按照地区L的方式对c1和c2进行比较
char c1 = '2';
char c2 = '4';
const std::ctype<char>& ct = std::use_facet<std::ctype<char>>(l);
bool result = ct.toupper(c1) < ct.toupper(c2);
//下边是一种形式
std::use_facet<std::ctype<char>>(l).toupper(c1);
struct lt_str_1 :
public binary_function<string, string, bool>{
struct lt_char{
const ctype<char>& ct;
lt_char(const ctype<char>& c) :ct(c){};
bool operator()(char x, char y)const
{
return ct.toupper(x) < ct.toupper(y);
}
};
locale loc;
const std::ctype<char>& ct;
lt_str_1(const std::locale& L = std::locale::classic())
:loc(L), ct(std::use_facet<std::ctype<char>>(loc)){};
bool operator()(const std::string& x, const string& y)const
{
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end(), lt_char(ct));
}
};
struct lt_str_2 :
public binary_function<string, string, bool>{
struct lt_char{
const char* tab;
lt_char(const char* t) :tab(t){}
bool operator()(char x, char y)const
{
return tab[x - CHAR_MIN] < tab[y - CHAR_MIN];
}
};
char tab[CHAR_MAX - CHAR_MIN + 1];
lt_str_2(const locale& L = locale::classic()){
const ctype<char>& ct = use_facet<ctype<char>>(L);
for (int i = CHAR_MIN; i <= CHAR_MAX; ++i)
{
tab[i - CHAR_MIN] = (char)i;
}
ct.toupper(tab, tab + (CHAR_MAX - CHAR_MIN + 1));
}
bool operator()(string& x, string& y)
{
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end(), lt_char(tab));
}
};
在任何的场合,lt_str_2明显比1块的多。
结论:
● 忽略大小写的字符串类是错误的抽象层面。C++标准库中的泛型算法是由策略参数化的,而你应该利
用这个事实。
● 词典字符串比较建立在字符比较之上。一旦你有了一个忽略大小写的字符比较函数对象,问题就解决
了。(而且你可以把那个函数对象重用于比较其他类型的字符序列,比如vector< char>,或字符串
表,或原始的C字符串。)
● 忽略大小写的字符比较比看起来难。除了在一个特定区域设置的场景之外,它没有意义,所以字符比
较函数对象需要储存区域设置信息。如果关系到速度,你应该写避免重复调用昂贵的方面操作的函数
对象。