比较操作员对字符串的含义是什么?

What is the meaning of the comparision operators for strings?

本文关键字:是什么 操作员 字符串 比较      更新时间:2023-10-16

我在C 中提供一堂课,因此我们的主题是关于操作员超载的,我正在使用我使用的" C 如何为Deitel编程"的教科书,其中有一个示例,其中他比较了2个字符串,这在逻辑上没有任何意义。

我的问题是下面的示例。与使用Alphabool相比,S2如何较小?

#include <iostream>
#include <string> 
using namespace std;
int main() {
    string s1{ "happy" };
    string s2{ " birthday" };
    string s3; // creates an empty string
    // test overloaded equality and relational operators
    cout << "s1 is "" << s1 << ""; s2 is "" << s2
        << ""; s3 is "" << s3 << '"'
        << "nnThe results of comparing s2 and s1:" 
        << "ns2 == s1 yields " << (s2 == s1)
        << "ns2 != s1 yields " << (s2 != s1)
        << "ns2 >  s1 yields " << (s2 > s1)
        << "ns2 <  s1 yields " << (s2 < s1)
        << "ns2 >= s1 yields " << (s2 >= s1)
        << "ns2 <= s1 yields " << (s2 <= s1)
        <<"Size of string s1 is:"<<s1.length()
        <<"Size if string s2 is:"<<s2.length();
}

s2开头的空格字符是在ASCII图表中s1开头的h之前,因此s2首先进行排序。幸运的是,如果那不是您想要的行为,则标准库包括使用不同排序算法的方法。例如,某些版本的std::lexicographical_compare采用类型Compare的参数,该参数可以是任何函数,即在且仅当两个元素按所需顺序中返回同一类型的两个元素并返回true。(您还可以使用"类似功能的对象",即实现operator()的类,该类别采用两个元素并返回bool(。同样,像std::setstd::map之类的容器以排序顺序保持其元素采用模板类型参数 Compare,该参数可按照您的喜好进行分类。

现在,与仅做s1 < s2相比,这听起来像是很多工作,是吗?好吧,如果您愿意,可以根据自己喜欢的方式创建自己的operator<自己的字符串类。这样做的一种方法是这样:

class myString: public std::string
{
    // ...
};
bool operator<(const myString &ms1, const myString &ms2)
{
    return std::lexicographical_compare(ms1.begin(), ms1.end(), ms2.begin(), ms2.end(), customComparison);
}

现在,您必须有点谨慎,具体取决于您的执行方式 - 在这种情况下,您需要小心,不要将myString对象交给期望std::string的物体,因为它会尝试像std::string一样对它们进行排序而是对象 - 但是有多种技术可以缓解,如果您决定这是您想做的事情。

正在使用的是词典比较。简单地解释这一点,当以这种方式比较两个字符串值时,首先出现在字典中的一个单词是将"仅比"第二个单词。基本上,将两个字符串值的每个字符逐一比较,直到一个值的ASCII代码的值低于另一个。

在您的特殊情况下,"生日"字符串开始时的空间比" happy"字符串的h的ASCII值低。因此先排序。

尽管 string旨在用于文本,并且所有文本都有编码,但比较运算符将字符串视为字节序列 - 数量值。因此,无论字节如何进入字符串,如果使用了编码的文本,则比较在数字序列上,在词典上。这意味着按元素进行比较的元素,直到一个序列的第一个差异或结束。

C 字符串类

请注意,此类与所使用的编码独立处理:如果用于处理多字节或可变长度字符的序列(例如UTF-8(,则此类的所有成员(例如长度或大小(,以及它的迭代器,仍然将以字节(不是实际编码字符(来运行。