练习5.14
编写一段程序,从标准输入中读取若干string对象并查找连续重复出现的单词。所谓连续重复出现的意思是:一个单词后面紧跟着这个单词本身。要求记录连续重复出现的最大次数以及对应单词。如果这样的单词存在,输出重复出现的最大次数;如果不存在,输出一条信息说明任何单词都没有连续出现过。例如,如果输入是
how now now now brown cow cow
那么输出应该表明单词now连续出现了3次。
解答:
#include <iostream>
#include <sstream>
#include <map>
#include <string>
using namespace std;
int main(){
string line, word_new, word_old;
map<string, int> res;
while (getline(cin, line)){
istringstream istr(line);
while (istr >> word_new){
if (word_new == word_old){
++res[word_old];
}
else{
res[word_new] = 1;
}
word_old = word_new;
}
}
map<string, int>::iterator max_it = res.begin();
for (auto it = res.begin(); it != res.end(); ++it){
if (max_it->second < it->second){
max_it = it;
}
}
cout << max_it->first << " appearance " << max_it->second << " times." << endl;
}
练习5.15
说明下列循环的含义并改正其中的错误。
(a)
for(int ix = 0; ix != sz; ++ix){...}
if (ix != sz)....
(b)
int ix;
for (ix != sz; ++ix) ...
(c)
for (int ix = 0; ix != sz; ++ix, ++ sz)...
解答:
(a) ix不能在for循环之外使用
int ix;
for(ix = 0; ix != sz; ++ix){...}
if (ix != sz)....
(b) for循环的三段少了初始化部分
int ix;
for(int ix = 0; ix != sz; ++ix){...}
(c) 这里没有语法错误,不过,有逻辑错误。如果不修改,这条语句将会无限循环的执行下去。
for (int ix = 0; ix != sz; ++ix)...
练习5.16
while循环特别适用于那种条件不变、反复执行操作的情况,例如,当未达到文件末尾时不断读取下一个值。for循环则更像是在按步骤迭代,他的索引值在某个范围内依次变化。根据每种循环的习惯用法各自写一段程序,然后分别用另一种循环改写。如果只能使用一种循环,你倾向于使用哪种循环呢?为什么?
解答:
互相转换的代码这里就不写了,之前也已经写过了。
如果只能选一种,我会选择for,它的功能要比while的更多一些,也同样能完成while的所有工作。
【2014.11.04补充】
近来在看《代码大全》感觉里面的实践经验更加值得我们去借鉴。当然,其中对这个问题也有一些描述,引用如下:
如果你需要一个执行次数固定的循环,那么for循环就是一个很好的选择。在C++、C、Java、Visual Basic以及大多数其他语言里,你都可以使用它。
可以用for循环来执行那些不要循环内部控制的简单操作。当循环控制解释简单的递增或递减,如对某一容器的元素进行迭代的时候,就可以使用for循环。for循环的关键之处在于,你在循环头处把它写好后就可以忘掉它了,无须在循环的内部做任何事情去控制它。如果存在一个必须使执行从循环跳出的条件,那么就应该改用while循环。
类似地,不要在for循环里通过直接修改下标值的方式迫使它终止,在这种情况下应该改用while循环。for循环就是为了简单的用途,更复杂的循环最好用while循环去处理。
练习5.17
假设两个包含整数的vector对象,编写一段程序,检验其中一个vector对象是否是另一个的前缀。为了实现这个目标,对于两个不等长的vector对象,只需跳出长度较短的那个,把它的所有元素和另一个vector对象比较即可。例如,两个vector对象的元素分别是0、1、1、2和0、1、1、2、3、5、8,则程序返回结果应该为真。
解答:
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> ivec1{ 0, 1, 1, 2}, ivec2{ 0, 1, 1, 2, 3, 5, 8 };
vector<int>::size_type min_len = (ivec1.size() < ivec2.size() ? ivec1.size() : ivec2.size());
bool result = true;
for (size_t i = 0; i != min_len; ++i){
if (ivec1.at(i) != ivec2.at(i)){
result = false;
break;
}
}
cout << boolalpha << result << endl;
}