第五单元
练习 5.1
什么是空语句?什么时候会用到空语句?
解:
只含义一个单独的分号的语句是空语句。如:;。
如果在程序的某个地方,语法上需要一条语句但是逻辑上不需要,此时应该使用空语句。
while (cin >> s && s != sought)
;
练习 5.2
写一段程序,使用if else语句实现把数字转换为字母成绩的要求。
#include <iostream>
#include <vector>
#include <string>
using std::vector; using std::string; using std::cout; using std::endl; using std::cin;
int main()
{
vector<string> scores = { "F", "D", "C", "B", "A", "A++" };
for (int g; cin >> g;)
{
string letter;
if (g < 60)
{
letter = scores[0];
}
else
{
letter = scores[(g - 50) / 10];
if (g != 100)
letter += g % 10 > 7 ? "+" : g % 10 < 3 ? "-" : "";
}
cout << letter << endl;
}
return 0;
}
练习 5.3
改写上一题的程序,使用条件运算符代替if else语句。
#include <iostream>
#include <vector>
#include <string>
using std::vector; using std::string; using std::cout; using std::endl; using std::cin;
int main()
{
vector<string> scores = { "F", "D", "C", "B", "A", "A++" };
int grade = 0;
while (cin >> grade)
{
string lettergrade = grade < 60 ? scores[0] : scores[(grade - 50) / 10];
lettergrade += (grade == 100 || grade < 60) ? "" : (grade % 10 > 7) ? "+" : (grade % 10 < 3) ? "-" : "";
cout << lettergrade << endl;
}
return 0;
}
练习 5.4
编写一段程序,使用一系列if语句统计从cin读入的文本中有多少元音字母。
#include <iostream>
using std::cout; using std::endl; using std::cin;
int main()
{
unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0;
char ch;
while (cin >> ch)
{
if (ch == 'a') ++aCnt;
else if (ch == 'e') ++eCnt;
else if (ch == 'i') ++iCnt;
else if (ch == 'o') ++oCnt;
else if (ch == 'u') ++uCnt;
}
cout << "Number of vowel a: \t" << aCnt << '\n'
<< "Number of vowel e: \t" << eCnt << '\n'
<< "Number of vowel i: \t" << iCnt << '\n'
<< "Number of vowel o: \t" << oCnt << '\n'
<< "Number of vowel u: \t" << uCnt << endl;
return 0;
}
练习 5.5
上面统计元音字母的程序存在一个问题:如果元音字母以大写形式出现,不会被统计在内。编写一段程序,既统计元音字母的小写形式,也统计元音字母的大写形式,也就是说,新程序遇到’a’和’A’都应该递增aCnt的值,以此类推。
#include <iostream>
using std::cin; using std::cout; using std::endl;
int main()
{
unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0;
char ch;
while (cin >> ch)
switch (ch)
{
case 'a':
case 'A':
++aCnt;
break;
case 'e':
case 'E':
++eCnt;
break;
case 'i':
case 'I':
++iCnt;
break;
case 'o':
case 'O':
++oCnt;
break;
case 'u':
case 'U':
++uCnt;
break;
}
cout << "Number of vowel a(A): \t" << aCnt << '\n'
<< "Number of vowel e(E): \t" << eCnt << '\n'
<< "Number of vowel i(I): \t" << iCnt << '\n'
<< "Number of vowel o(O): \t" << oCnt << '\n'
<< "Number of vowel u(U): \t" << uCnt << endl;
return 0;
}
练习 5.6
修改统计元音字母的程序,使其也能统计空格、制表符、和换行符的数量。
#include <iostream>
using std::cin; using std::cout; using std::endl;
int main()
{
unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0, spaceCnt = 0, tabCnt = 0, newLineCnt = 0;
char ch;
while (cin >> std::noskipws >> ch) //noskipws(no skip whitespce)
switch (ch)
{
case 'a':
case 'A':
++aCnt;
break;
case 'e':
case 'E':
++eCnt;
break;
case 'i':
case 'I':
++iCnt;
break;
case 'o':
case 'O':
++oCnt;
break;
case 'u':
case 'U':
++uCnt;
break;
case ' ':
++spaceCnt;
break;
case '\t':
++tabCnt;
break;
case '\n':
++newLineCnt;
break;
}
cout << "Number of vowel a(A): \t" << aCnt << '\n'
<< "Number of vowel e(E): \t" << eCnt << '\n'
<< "Number of vowel i(I): \t" << iCnt << '\n'
<< "Number of vowel o(O): \t" << oCnt << '\n'
<< "Number of vowel u(U): \t" << uCnt << '\n'
<< "Number of space: \t" << spaceCnt << '\n'
<< "Number of tab char: \t" << tabCnt << '\n'
<< "Number of new line: \t" << newLineCnt << endl;
return 0;
}
使用 std::noskipws可以保留默认跳过的空格。
练习 5.7
修改统计元音字母的程序,使其能统计含以下两个字符的字符序列的数量:ff、fl和fi。
#include <iostream>
using std::cin; using std::cout; using std::endl;
int main()
{
unsigned aCnt = 0, eCnt = 0, iCnt = 0, oCnt = 0, uCnt = 0, spaceCnt = 0, tabCnt = 0, newLineCnt = 0, ffCnt = 0, flCnt = 0, fiCnt = 0;
char ch, prech = '\0';
while (cin >> std::noskipws >> ch)
{
switch (ch)
{
case 'a':
case 'A':
++aCnt;
break;
case 'e':
case 'E':
++eCnt;
break;
case 'i':
if (prech == 'f') ++fiCnt;
case 'I':
++iCnt;
break;
case 'o':
case 'O':
++oCnt;
break;
case 'u':
case 'U':
++uCnt;
break;
case ' ':
++spaceCnt;
break;
case '\t':
++tabCnt;
break;
case '\n':
++newLineCnt;
break;
case 'f':
if (prech == 'f') ++ffCnt;
break;
case 'l':
if (prech == 'f') ++flCnt;
break;
}
prech = ch;
}
cout << "Number of vowel a(A): \t" << aCnt << '\n'
<< "Number of vowel e(E): \t" << eCnt << '\n'
<< "Number of vowel i(I): \t" << iCnt << '\n'
<< "Number of vowel o(O): \t" << oCnt << '\n'
<< "Number of vowel u(U): \t" << uCnt << '\n'
<< "Number of space: \t" << spaceCnt << '\n'
<< "Number of tab char: \t" << tabCnt << '\n'
<< "Number of new line: \t" << newLineCnt << '\n'
<< "Number of ff: \t" << ffCnt << '\n'
<< "Number of fl: \t" << flCnt << '\n'
<< "Number of fi: \t" << fiCnt << endl;
return 0;
}
练习 5.8
编写一段程序,从标准输入中读取若干string对象并查找连续重复出现的单词,所谓连续重复出现的意思是:一个单词后面紧跟着这个单词本身。要求记录连续重复出现的最大次数以及对应的单词。如果这样的单词存在,输出重复出现的最大次数;如果不存在,输出一条信息说明任何单词都没有连续出现过。
#include <iostream>
#include <string>
using std::cout; using std::cin; using std::endl; using std::string; using std::pair;
int main()
{
pair<string, int> max_duplicated;
int count = 0;
for (string str, prestr; cin >> str; prestr = str)
{
if (str == prestr) ++count;
else count = 0;
if (count > max_duplicated.second) max_duplicated = { prestr, count };
}
if (max_duplicated.first.empty()) cout << "There's no duplicated string." << endl;
else cout << "the word " << max_duplicated.first << " occurred " << max_duplicated.second + 1 << " times. " << endl;
return 0;
}
练习 5.9
假设有两个包含整数的vector对象,编写一段程序,检验其中一个vector对象是否是另一个的前缀。 为了实现这一目标,对于两个不等长的vector对象,只需挑出长度较短的那个,把它的所有元素和另一个vector对象比较即可。 例如,如果两个vector对象的元素分别是0、1、1、2 和 0、1、1、2、3、5、8,则程序的返回结果为真。
#include <iostream>
#include <vector>
using std::cout; using std::vector;
bool is_prefix(vector<int> const& lhs, vector<int> const& rhs)
{
if(lhs.size() > rhs.size())
return is_prefix(rhs, lhs);
for(unsigned i = 0; i != lhs.size(); ++i)
if(lhs[i] != rhs[i]) return false;
return true;
}
int main()
{
vector<int> l{ 0, 1, 1, 2 };
vector<int> r{ 0, 1, 1, 2, 3, 5, 8 };
cout << (is_prefix(r, l) ? "yes\n" : "no\n");
return 0;
}
练习 5.10
使用do while循环重复地执行下述任务: 首先提示用户输入两个string对象,然后挑出较短的那个并输出它。
#include <iostream>
#include <string>
using std::cout; using std::cin; using std::endl; using std::string;
int main()
{
string rsp;
do {
cout << "Input two strings: ";
string str1, str2;
cin >> str1 >> str2;
cout << (str1 <= str2 ? str1 : str2)
<< " is less than the other. " << "\n\n"
<< "More? Enter yes or no: ";
cin >> rsp;
} while (!rsp.empty() && tolower(rsp[0]) == 'y');
return 0;
}
练习 5.11
从标准输入中读取string对象的序列直到连续出现两个相同的单词或者所有的单词都读完为止。 使用while循环一次读取一个单词,当一个单词连续出现两次时使用break语句终止循环。 输出连续重复出现的单词,或者输出一个消息说明没有任何单词是连续重复出现的。
#include <iostream>
#include <string>
using std::cout; using std::cin; using std::endl; using std::string;
int main()
{
string read, tmp;
while (cin >> read)
if (read == tmp) break; else tmp = read;
if (cin.eof()) cout << "no word was repeated." << endl; //eof(end of file)判断输入是否结束,或者文件结束符,等同于 CTRL+Z
else cout << read << " occurs twice in succession." << endl;
return 0;
}
练习 5.12
使其找到的重复单词必须以大写字母开头。
#include <iostream>
using std::cin; using std::cout; using std::endl;
#include <string>
using std::string;
int main()
{
string curr, prev;
bool no_twice = true;
while (cin >> curr)
{
if (isupper(curr[0]) && prev == curr)
{
cout << curr << ": occurs twice in succession." << endl;
no_twice = false;
break;
}
prev = curr;
}
if (no_twice)
cout << "no word was repeated." << endl;
return 0;
}
练习 5.13
从标准输入读取两个整数,输出第一个数除以第二个数的结果。
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
int i, j;
cin >> i >> j;
cout << i / j << endl;
return 0;
}
练习 5.14
修改你的程序,使得当第二个数是0时抛出异常。先不要设定catch子句,运行程序并真的为除数输入0,看看会发生什么?
#include <iostream>
#include <stdexcept>
int main(void)
{
int i, j;
std::cin >> i >> j;
if (j == 0)
throw std::runtime_error("divisor is 0");
std::cout << i / j << std::endl;
return 0;
}
练习 5.15
修改上一题的程序,使用try语句块去捕获异常。catch子句应该为用户输出一条提示信息,询问其是否输入新数并重新执行try语句块的内容。
#include <iostream>
#include <stdexcept>
using std::cin; using std::cout; using std::endl; using std::runtime_error;
int main(void)
{
for (int i, j; cout << "Input two integers:\n", cin >> i >> j; )
{
try
{
if (j == 0)
throw runtime_error("divisor is 0");
cout << i / j << endl;
}
catch (runtime_error err)
{
cout << err.what() << "\nTry again? Enter y or n" << endl;
char c;
cin >> c;
if (!cin || c == 'n')
break;
}
}
return 0;
}