字符串的比较运算符的含义是什么?

时间:2017-05-03 07:00:56

标签: c++ string

我正在用C ++编写一个类,所以我们的主题是关于运算符重载,从我正在使用的教科书" C ++如何编写Deitel"并且有这个例子,他比较了两个逻辑上没有任何意义的字符串。

我的问题在以下示例中。与使用alphabool相比,为什么s2比s1小?

#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 << '\"'
        << "\n\nThe 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();

}

3 个答案:

答案 0 :(得分:2)

s2开头的空格字符位于ASCII图表h开头的s1之前,因此s2首先排序。幸运的是,如果这不是您想要的行为,标准库包括使用不同排序算法的方法。例如,某些版本的std::lexicographical_compare采用类型为Compare的参数,该参数可以是采用相同类型的两个元素的任何函数,当且仅当这两个元素位于时,才返回true所需的顺序。 (您也可以使用&#34;类似函数的对象&#34;,即实现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个对象交给那些期待{{1}的东西。因为它会试着像std::string对象那样对它们进行排序 - 但是如果你决定要做某些事情,有各种各样的技巧来减轻它们。

答案 1 :(得分:2)

正在使用的是Lexicographical Comparison。简单地解释一下,当以这种方式比较两个字符串值时,首先出现在字典中的一个单词将被认为是“小于”第二个单词。基本上,两个字符串值的每个字符都是逐个比较的,直到一个ASCII码的值低于另一个的ASCII码。

在您的特定情况下,“birthday”字符串开头的空格的ASCII值低于“happy”字符串的h值。所以首先排序。

答案 2 :(得分:0)

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

C++ String class

  

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