地域性与忽略大小写的字符串比较

本文介绍如何在C++中实现忽略大小写的字符串比较,包括通过自定义比较函数对象来适应不同区域设置的需求,并提供了具体的代码实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#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字符串。)
● 忽略大小写的字符比较比看起来难。除了在一个特定区域设置的场景之外,它没有意义,所以字符比
较函数对象需要储存区域设置信息。如果关系到速度,你应该写避免重复调用昂贵的方面操作的函数
对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值