C++ Primer Plus(第六版)编程练习答案 第16章 string类和标准模板库

本章所有编程练习的工程源码可在此处下载(点击此链接下载),供大家参考交流!

 

1. 回文指的是顺读和逆读都一样的字符串。例如,“tot”和“otto”都是简短的回文。编写一个程序,让用户输入字符串,并将字符串引用传递给一个bool函数。如果字符串时回文,该函数将返回true,否则返回false。此时,不要担心诸如大小写、空格和标点符号这些复杂的问题。即这个简单的版本将拒绝"Otto”和“Madam, I'm Adam”。请查看附录F中的字符串方法列表,以简化这项任务。

本题要求我们编写程序来识别回文,我们需要编写一个bool函数来判断是否是回文,判断回文的方法有很多种,在这里因为不需要考虑标点符号和大小写等问题,所以我们只需要考虑最简单的方法即可,即将原字符串反转,倒序生成一个新字符串,判断新生成的字符串与原字符串是否严格相等。

16.1.cpp代码如下所示:

// 16.1.cpp -- judge if a string is hui-string
#include "stdafx.h"
#include 
#include 
using namespace std;
bool isHui(const string & str);

int main()
{
    cout << "Test begin.\n";
    cout << "Please enter your input (empty input to quit): ";
    string input;
    getline(cin, input);
    while (cin && input.size() > 0)
    {
        if (isHui(input))
            cout << "What you input is a Hui string!\n";
        else
            cout << "What you input is not a Hui string!\n";
        cout << "Please enter your input (empty input to quit): ";
        getline(cin, input);
    }
    cout << "Test end. Quit.\n";
    system("pause");
    return 0;
}

bool isHui(const string & str)
{
    string rev(str.rbegin(), str.rend());
    return (str == rev);
}

运行结果如下图所示:

C++ Primer Plus(第六版)编程练习答案 第16章 string类和标准模板库_第1张图片

从结果图可以看出,该程序可以识别简单的回文,但拒绝大小写或标点符号等形式的回文。

 

2. 与编程练习1中给出的问题相同,但要考虑诸如大小写、空格和标点符号这样的复杂问题。即“Madam, I'm Adam”将作为回文来测试。例如,测试函数可能会将字符串缩略为“madamimadam”,然后测试倒过来是否一样。不要忘了有用的cctype库,您可能从中找到几个有用的STL函数,尽管不一定非要使用它们。

本题要求在考虑空格、大小写和标点符号的情况下来测试回文,整体程序框架可以与上一题完全一样,只需要修改判断是否是回文的bool函数。

在判断是否是回文之前,我们必须把空格和标点符号去掉,然后把大小写归一化才行。对于去掉空格和标点符号,最简单的方法是调用cctype库中的erase()函数,该函数会删去指定的字符,那么我们可以使用isalpha()函数来判断是否是字母,如果不是字母,即空格或者各式各样的标点符号,则调用erase()函数将其删去。对于大小写的归一化,我们可以统一到一种格式上,比如按照题目中举的例子,就是统一都格式化成小写,那么就是使用tolower()函数。

在这里特别注意两个问题,第一个问题是对于在循环中删去字符的情况,这种情况下我们不需要在删去字符之后加上i++;语句,因为此时本来下标为i的字符已经被删去了,后面的本来下标为i+1的字符会自动顶上来,因此下一次还是去处理下标为i的字符;第二个问题是对于将下标为i的字符格式化为小写,由于此时i是一个迭代器,是一个字符串引用,因此我们需要使用*i来获取它的值。

16.2.cpp代码如下所示:

// 16.2.cpp -- judge if a string is a Hui-string (contains the space and symbols)

#include "stdafx.h"
#include 
#include 
#include 
using namespace std;
bool isHui(const string & str);

int main()
{
    cout << "Test begin.\n";
    cout << "Please enter your input (empty input to quit): ";
    string input;
    getline(cin, input);
    while (cin && input.size() > 0)
    {
        if (isHui(input))
            cout << "What you input is a Hui string!\n";
        else
            cout << "What you input is not a Hui string!\n";
        cout << "Please enter your input (empty input to quit): ";
        getline(cin, input);
    }
    cout << "Test end. Quit.\n";
    system("pause");
    return 0;
}

bool isHui(const string & str)
{
    string str_test = str;
    for (auto i = str_test.begin(); i != str_test.end();)
    {
        if (!isalpha(*i))
        {
            i = str_test.erase(i);
            continue;
        }
        else
        {
            *i = tolower(*i);
            i++;
        }
    }
    string rev(str_test.rbegin(), str_test.rend());
    return (str_test == rev);
}

运行结果如下图所示:

C++ Primer Plus(第六版)编程练习答案 第16章 string类和标准模板库_第2张图片

从上图的第三个输入可以看出,该函数忽略空格,从上图的第四个输入可以看出,该函数忽略大小写,从上图的第五个输入可以看出,该函数忽略标点符号。

 

3. 修改程序清单16.3,使之从文件中读取单词。一种方案是,使用vector对象而不是string数组。这样便可以使用push_back()将数据文件中的单词复制到vector对象中,并使用size()来确定单词列表的长度。由于程序应该每次从文件中读取一个单词,因此应使用运算符>>而不是getline()。文件中包含的单词应该用空格、制表符或换行符分隔。

本题要求在程序清单16.3的基础上进行修改,不是直接获取单词列表,而是改为从文件中去读取单词。题中给出的思路是将string数组修改为vector对象来储存读取的单词列表,我们可以按照这个思路来进行修改。

首先,我们在程序目录下生成一个wordlist.txt文件,输入程序清单16.3的string数组的单词,用空格分开,如下图所示:

C++ Primer Plus(第六版)编程练习答案 第16章 string类和标准模板库_第3张图片

接下来我们得声明一个读取文件的fin,对打不开文件的情况进行处理,这些内容可以阅读《C++ Primer Plus (第六版)》的第17章详细学习。我们声明一个名叫wordlist的evctor对象,通过fin来读取文件中的单词,使用push_back()函数将这些单词放入wordlist中,然后获取wordlist的长度。

对于后面具体的hangman游戏的处理,我们可以完全使用程序清单16.3一模一样的代码即可。

16.3.cpp代码如下所示:

// 16.3.cpp -- a new hangman

#include "stdafx.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 

//const string wordlist[NUM] = { "apiary", "beetle", "cereal",
//"danger", "ensign", "florid", "garage", "health", "insult",
//"jackal", "keeper", "loaner", "manage", "nonce", "onset",
//"plaid", "quilt", "remote", "stolid", "train", "useful",
//"valid", "whence", "xenon", "yearn", "zippy" };


int main()
{
    using namespace std;

你可能感兴趣的:(C++,C++,Primer,Plus,(第六版),中文版,编程练习,C++,Primer,Plus,编程练习,第16章)