题目
1.回文指的是顺读和逆读都一样的字符串。例如,“tot”和“otto”都是简短的回文。编写一个程序,让用户输入字符串,并将字符串引用传递给一个bool函数。如果字符串时回文,该函数将返回true,否则返回false.此时,不要担心诸如大小写、空格和标点符号这些复杂的问题。即这个简单的版本将拒绝 “Otto” 和 “Madam, I’m Adam”。请查看附录F中的字符串方法列表,以简化这项任务。
2.与编程练习1中给出的问题相同,但要考虑诸如大小写、空格和标点符号这样的复杂问题。即“Madam, I’m Adam”将作为回文来测试。例如,测试函数可能会将字符串缩略为“madamimadam”,然后测试倒过来是否一样。不要忘了有用的cctype库,您可能从中找到几个有用的STL函数,尽管不一定非要使用它们。
3.修改程序清单16.3,使之从文件中读取单词。一种方案是,使用vector< string>对象而不是string数组。这样便可以使用push_back()将数据文件中的单词复制到vector< string>对象中,并使用size()来确定单词列表的长度。由于程序应该每次从文件中读取一个单词,因此应使用运算符>>而不是getline()。文件中包含的单词应该用空格、制表符或换行符分隔。
4.编写一个具有老式风格接口的函数,其原型如下:
int reduce(long ar[], int n);
实参应是数组名和数组中的元素个数。该函数对数组进行排序,删除重复的值,返回缩减后数组中的元素数目。请使用STL函数编写该函数(如果决定使用通用的unique()函数,请注意它将返回结果区间的结尾)。使用一个小程序测试该函数。
5.问题与编程练习4相同,但要编写一个模板函数:
template< class T>
int reduce(T ar[], int n):
在一个使用long实例和string实例的小程序中测试该函数。
6.使用STL queue模板类而不是第12章的Queue类,重新编写程序清单12.12所示的示例。
7.彩票卡是一个常见的游戏。卡片上带编号的圆点,其中一些圆点被随机选中。编写一个lotto()函数,它接受两个参数。第一个参数是彩票卡上圆点的个数,第二个参数是随机选择的圆点个数。该函数返回一个vector对象,其中包含(按排列后的顺序)随机选择的号码。例如,可以这样使用该函数:
vector< int> winners;
winners = Lotto(51,6);
这样将把一个矢量赋给winner,该矢量包含1~51中随机选定的6个数字。注意,仅仅使用rand()无法完成这项任务,因它会生成重复的值。提示:让函数创建一个包含所有可能值的矢量,使用 random_shuffle(),然后通过打乱后的矢量的第一个值来获取值。编写一个小程序来测试这个函数。
8.Mat和Pat希望邀请他们的朋友来参加派对。他们要编写一个程序完成下面的任务。
- 让Mat输入他朋友的姓名列表。姓名存储在一个容器中,然后按排列后的顺序显示出来。
- 让Pat输入她朋友的姓名列表。姓名存储在另一个容器中,然后按排列后的顺序显示出来。
- 创建第三个容器,将两个列表合并,删除重复的部分,并显示这个容器的内容。
9.相对于数组,在链表中添加和删除元素更容易,但排序速度更慢。这就引出了一种可能性:相对于使用链表算法进行排序,将链表复制到数组中,对数组进行排序,再将排序后的结果复制到链表中的速度可能更快;但这也可能占用更多的内存。请使用如下方法检验上述假设。
a. 创建大型vector< int>对象vi0,并使用rand()给它提供初始值。
b. 创建vector< int>对象vi和list< int>对象li,它们的长度都和初始值与vi0相同。
c. 计算使用STL算法sort()对vi进行排序所需的时间,再计算使用list的方法sort()对li进行排序所需的时间。
d. 将li重置为排序的vi0的内容,并计算执行如下操作所需的时间:将li的内容复制到vi中,对vi进行排序,并将结果复制到li中。
要计算这些操作所需的时间,可使用ctime库中的clock()。正如程序清单5.14演示的,可使用下面的语句来获取开始时间:
clock_t start = clock();
再在操作结束后使用下面的语句获取经过了多长时间:
clock_t end = clock();
cout << (double)(end - start)/CLOCKS_PER_SEC;
这种测试并非绝对可靠,因为结果取决于很多因素,如可用内存量、是否支持多处理以及数组(列表)的长度(随着要排序的元素数增加,数组相对于列表的效率将更明显)。另外,如果编译器提供了默认生成方式和发布生成方式,请使用发布生成方式。鉴于当今计算机的速度非常快,要获得有意义的结果,可能需要使用尽可能大的数组。例如,可尝试包含100000、1000000和10000000个元素。
10.请按如下方式修改程序清单16.9(vect3.cpp)。
a. 在结构Review中添加成员price。
b. 不使用vector< Review>来存储输入,而使用vector<shared_ptr< Review>>。别忘了,必须使用new返回的指针来初始化shared_ptr。
c.在输入阶段结束后,使用一个循环让用户选择如下方式之一显示书籍:按原始顺序显示、按字母表顺序显示、按评级升序显示、按评级降序显示、按价格升序显示、按价格降序显示、退出。
下面是一种可能的解决方案:获取输入后,再创建一个shared_ptr矢量,并用原始数组初始化它。定义一个对指向结构的指针进行比较的operator<()函数,并使用它对第二个矢量进行排序,让其中的shared_ptr按其指向的对象中的书名排序。重复上述过程,创建按rating和price排序的shared_ptr矢量。请注意,通过使用rbegin()和rend(),可避免创建按相反的顺序排列的shared_ptr矢量。
程序
#include <iostream>
#include <string>
using namespace std;
bool IsPlalindrome(const string &s);
int main()
{
cout<<"Enter a string:\n";
string s;
getline(cin,s);
while(cin&&s.size()>0)
{
if(IsPlalindrome(s))
cout<<s<<" is a plalindrome.\n";
else
cout<<s<<" is not a plalindrome.\n";
cout<<"Enter the next string:\n";
getline(cin,s);
}
cout<<"Bye.\n";
return 0;
}
bool IsPlalindrome(const string &s)
{
string r(s.rbegin(),s.rend());
return(s==r);
}
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
bool IsPlalindrome(const string &s);
int main()
{
cout<<"Enter a string:\n";
string s;
getline(cin,s);
while(cin&&s.size()>0)
{
if(IsPlalindrome(s))
cout<<s<<" is a plalindrome.\n";
else
cout<<s<<" is not a plalindrome.\n";
cout<<"Enter the next string:\n";
getline(cin,s);
}
cout<<"Bye.\n";
return 0;
}
bool IsPlalindrome(const string &s)
{
string temp;
for(int i=0;i<s.length();i++)
{
if(isalpha(s[i]))
{
temp.push_back(tolower(s[i]));
}
}
string r(temp.rbegin(),temp.rend());
return(temp==r);
}
// hangman.cpp -- some string methods
#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <cctype>
#include <vector>
#include <fstream>
using namespace std;
int main()
{
ifstream fin;
fin.open("wordlist.txt");
if (fin.is_open() == false)
{
cerr << "Can't open file. Bye.\n";
exit(EXIT_FAILURE);
}
vector<string> wordlist;
string temp;
while(fin>>temp)
{
wordlist.push_back(temp);
}
fin.close();
const int NUM=wordlist.size();
srand(time(0));
char play;
cout << "Will you play a word game? <y/n> ";
cin >> play;
play = tolower(play);
while (play == 'y')
{
string target = wordlist[std::rand() % NUM];
int length = target.length();
string attempt(length, '-');
string badchars;
int guesses = 6;
cout << "Guess my secret word. It has " << length
<< " letters, and you guess\n"
<< "one letter at a time. You get " << guesses
<< " wrong guesses.\n";
cout << "Your word: " << attempt << endl;
while (guesses > 0 && attempt != target)
{
char letter;
cout << "Guess a letter: ";
cin >> letter;
if (badchars.find(letter) != string::npos
|| attempt.find(letter) != string::npos)
{
cout << "You already guessed that. Try again.\n";
continue;
}
int loc = target.find(letter);
if (loc == string::npos)
{
cout << "Oh, bad guess!\n";
--guesses;
badchars += letter; // add to string
}
else
{
cout << "Good guess!\n";
attempt[loc]=letter;
// check if letter appears again
loc =