8.8.4 比较字符串
我们有一整套比较运算符,用来比较两个字符串对象,或者比较一个字符串对象与一个字符串字面值。string类中对下列运算符实现了运算符重载:
- == != < <= > >=
下面是使用这些运算符的示例:
- string dog1("St Bernard");
- string dog2("Tibetan Mastiff");
- if(dog1 < dog2)
- cout << "dog2 comes first!" << endl;
- else if(dog1 > dog2)
- cout << "dog1 comes first!" << endl;
当我们比较两个字符串时,实际上是比较对应的字符,直到发现一对不同的字符,或者到达一个或两个字符串的末尾。当发现两个对应字符不相同时,字符代码的值决定比较结果。如果没有发现不同的字符对,那么字符较少的字符串小于另一个字符串。如果两个字符串包含相同的字符个数,而且对应的字符也相同,则这两个字符串相等。
试一试:比较字符串
本例说明了如何用极其低效的排序方法来使用比较运算符。代码如下:
- // Ex8_10.cpp
- // Comparing and sorting words
- #include <iostream>
- #include <iomanip>
- #include <string>
- using std::cin;
- using std::cout;
- using std::endl;
- using std::ios;
- using std::setiosflags;
- using std::setw;
- using std::string;
-
- string* sort(string* strings, size_t count)
- {
- bool swapped = false;
- while(true)
- {
- for(size_t i = 0 ; i<count-1 ; i++)
- {
- if(strings[i] > strings[i+1])
- {
- swapped = true;
- strings[i].swap(strings[i+1]);
- }
- }
- if(!swapped)
- break;
- swapped = false;
- }
- return strings;
- }
-
- int main()
- {
- const size_t maxstrings = 100;
- string strings[maxstrings];
- size_t nstrings = 0;
- size_t maxwidth = 0;
-
- // Read up to 100 words into the strings array
- while(nstrings < maxstrings)
- {
- cout << "Enter a word or press Enter to end: ";
- getline(cin, strings[nstrings]);
- if(maxwidth < strings[nstrings].length())
- maxwidth = strings[nstrings].length();
- if(strings[nstrings].empty())
- break;
- ++nstrings;
- }
-
- // Sort the input in ascending sequence
- sort(strings,nstrings);
- cout << endl
- << "In ascending sequence, the words you entered are:"
- << endl
- << setiosflags(ios::left); // Left-justify the output
- for(size_t i = 0 ; i<nstrings ; i++)
- {
- if(i % 5 == 0)
- cout << endl;
- cout << setw(maxwidth+2) << strings[i];
- }
- cout << endl;
- return 0;
- }
下面是该示例的一些典型输出:
- Enter a word or press Enter to end: loquacious
- Enter a word or press Enter to end: transmogrify
- Enter a word or press Enter to end: abstemious
- Enter a word or press Enter to end: facetious
- Enter a word or press Enter to end: xylophone
- Enter a word or press Enter to end: megaphone
- Enter a word or press Enter to end: chauvinist
- Enter a word or press Enter to end:
-
- In ascending sequence, the words you entered are:
-
- abstemious chauvinist facetious loquacious megaphone
- transmogrify xylophone
示例说明
sort()函数最有趣的部分是它接受两个实参:字符串数组的地址与数组元素的个数。
该函数使用冒泡排序法,方法是按顺序扫描元素并逐个比较它们。所有工作都在while循环中完成:
- bool swapped = false;
- while(true)
- {
- for(size_t i = 0 ; i<count-1 ; i++)
- {
- if(strings[i] > strings[i+1])
- {
- swapped = true;
- strings[i].swap(strings[i+1]);
- }
- }
- if(!swapped)
- break;
- swapped = false;
- }
上述代码中用>运算符比较strings数组中的逐个元素。如果一对元素中第一个元素大于第二个元素,就交换这两个元素。在这种情况下,通过调用一个string对象的swap()函数,并将另一个string对象作为实参来交换元素。当有必要继续时,对整个数组的元素逐个比较并进行交换。然后,元素就变成了升序排列。bool变量swapped充当指示器,表明在给定的通道(pass)上有没有发生交换。仅当交换两个元素时,才会将它设置为true。
main()函数最多能在一个循环中向字符串数组中读入100个单词:
- while(nstrings < maxstrings)
- {
- cout << "Enter a word or press Enter to end: ";
- getline(cin, strings[nstrings]);
- if(maxwidth < strings[nstrings].length())
- maxwidth = strings[nstrings].length();
- if(strings[nstrings].empty())
- break;
- ++nstrings;
- }
这里getline()函数从cin中读取字符,直至读到'\n'。输入存储在第二个实参strings[nstrings]指定的string对象中。只需按下Enter键就会导致一个empty()字符串,因此当读取的最后一个string对象的empty()函数返回true时终止循环。maxwidth变量用来记录输入的最长字符串的长度。在对输入内容进行排序以后的输出过程中会用到它。
调用sort()函数可以按升序对strings数组中的内容进行排序。结果是在一个循环中输出:
- cout << endl
- << "In ascending sequence, the words you entered are:"
- << endl
- << setiosflags(ios::left); // Left-justify the output
- for(size_t i = 0 ; i<nstrings ; i++)
- {
- if(i % 5 == 0)
- cout << endl;
- cout << setw(maxwidth+2) << strings[i];
- }
这段代码在宽度为maxwidth+2个字符的字段中输出各个元素。因为调用了setiosflags()操作符,实参为ios::left,所以字段中的各个单词保持左对齐。与setw()操作符不同,在重置之前setiosflags()操作符仍然有效。