我正在用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();
}
答案 0 :(得分:2)
s2
开头的空格字符位于ASCII图表h
开头的s1
之前,因此s2
首先排序。幸运的是,如果这不是您想要的行为,标准库包括使用不同排序算法的方法。例如,某些版本的std::lexicographical_compare
采用类型为Compare
的参数,该参数可以是采用相同类型的两个元素的任何函数,当且仅当这两个元素位于时,才返回true
所需的顺序。 (您也可以使用&#34;类似函数的对象&#34;,即实现operator()
的类,它接受两个元素并返回bool
)。类似地,像std::set
和std::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
用于文本,并且所有文本都有编码,但比较运算符将字符串视为字节序列 - 数值。因此,无论字节如何进入字符串,如果文本使用哪种编码,则按字典顺序进行数字序列的比较。这意味着逐个元素比较,直到一个或两个序列的第一个差异或结束。
请注意,此类独立于所使用的编码处理字节:如果用于处理多字节或可变长度字符(例如UTF-8)的序列,则此类的所有成员(例如长度或大小),以及它的迭代器,仍将以字节(不是实际编码字符)的形式运行。