C++ Primer Plus 第六版 第十六章課後編程練習答案

1.

play.cpp

#include <iostream>
using namespace std;
#include <string>

bool IsHui(const string &str);

int main()
{
    cout << "Enter input(empty input to quit): ";
    string input;
    getline(cin, input);
    while (cin && input.size()>0)
    {
        if(IsHui(input))
            cout << "Yes.\n";
        else
            cout << "No.\n";
        cout << "Enter input(empty input to quit): ";
        getline(cin, input);
    }
    cout << "End.\n";

    return 0;
}

bool IsHui(const string &str)
{
    string f(str.rbegin(), str.rend());//字符串反轉
    return (str == f);
}

2.

本題要求在考慮空格、大小寫和標點符號的情況下來測試迴文,整體程序框架可以與上一題完全一樣,只需要修改判斷是否是迴文的bool函數。

在判斷是否是迴文之前,我們必須把空格和標點符號去掉,然後把大小寫歸一化才行。對於去掉空格和標點符號,最簡單的方法是調用cctype庫中的erase()函數,該函數會刪去指定的字符,那麼我們可以使用isalpha()函數來判斷是否是字母,如果不是字母,即空格或者各式各樣的標點符號,則調用erase()函數將其刪去。對於大小寫的歸一化,我們可以統一到一種格式上,比如按照題目中舉的例子,就是統一都格式化成小寫,那麼就是使用tolower()函數。

#include <iostream>
using namespace std;
#include <string>
#include <cctype>

bool IsHui(const string &str);

int main()
{
    cout << "Enter input(empty input to quit): ";
    string input;
    getline(cin, input);
    while (cin && input.size()>0)
    {
        if(IsHui(input))
            cout << "Yes.\n";
        else
            cout << "No.\n";
        cout << "Enter input(empty input to quit): ";
        getline(cin, input);
    }
    cout << "End.\n";

    return 0;
}

bool IsHui(const string &str)
{
    string str_test = str;//必須有
    for(auto i = str_test.begin(); i != str_test.end();) //i是str_test各元素所在的位置,*i是元素
    {
        if(!isalpha(*i))
        {
            i = str_test.erase(i);//該位置的元素去掉
            continue;
        }
        else
        {
            *i = tolower(*i);
            i++;
        }
    }
    string f(str_test.rbegin(), str_test.rend());
    return (str_test == f);
}

3.

play.cpp

//改自清單16.3
#include <iostream>
using namespace std;
#include <cctype>
#include <cstdlib>
#include <ctime>
#include <string>
#include <vector>
#include <fstream>

int main()
{
    const string filename = "wordlist.txt";
    vector<string> wordlist;
    ifstream fin;
    fin.open(filename.c_str());
    if(fin.is_open() == false)
    {
        cerr << "Can't open file.Bye.\n";
        exit(EXIT_FAILURE);
    }
    string temp;
    while (fin >> temp)
        wordlist.push_back(temp);

//以下按清單16.3
    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[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;
            }
            else
            {
                cout << "Good guess!\n";
                attempt[loc] = letter;
                loc = target.find(letter, loc + 1);
                while (loc != string::npos)
                {
                    attempt[loc] = letter;
                    loc = target.find(letter, loc + 1);
                }
            }
            cout << "Your word: " << attempt << endl;
            if(attempt != target)
            {
                if(badchars.length() > 0)
                    cout << "Bad choices: " << badchars << endl;
                cout << guesses << " bad guesses left\n";
            }
        }
        if(guesses > 0)
            cout << "That's right!\n";
        else
            cout << "Sorry, the word is " << target << ".\n";
        cout << "Will you play another? <y/n>";
        cin >> play;
        play = tolower(play);
    }
    cout << "Bye\n";

    return 0;
}

4.

play.cpp

//排序,去重
#include <iostream>
using namespace std;
#include <algorithm>

int reduce(long ar[], int n);

int main()
{
    long arr_test[10] = {156, 124, 23, 43, 35, 23, 124, 199, 210, 56};
    cout << "Original array:\n";
    for(int i = 0; i < 10; i++)
        cout << arr_test[i] << " ";
    cout << endl;

    int newsize = reduce(arr_test, 10);//返回縮減後數組中的元素數目
    cout << "Newsize: " << newsize << endl;
    cout << "After reduction, array:\n";
    for(int i = 0; i < newsize; i++)
        cout << arr_test[i] << " ";
    cout << endl;

    return 0;
}

int reduce(long ar[], int n)
{
    sort(ar, ar + n);//排序
    long * arr_new;
    arr_new = unique(ar, ar + n);//去重
    //用unique()函數返回結果區間結尾的特點,將該結尾指針地址賦給一個long指針,將該地址減去實參的數組名地址,即是縮減後的元素數目
    return arr_new - ar;
}

5.

本題是編寫練習4的延伸,要求我們把原本的long數組修改爲模板類,然後分別使用long實例和string實例來驗證。

我們依然沿用編程練習4的思路和程序框架,首先把reduce()函數的實參進行修改,ar[]現在不再是long數組了,而是模板類T的數組,那麼對應的在函數內部聲明的new_ar指針的類型也就相應變成T模板類。

play.cpp

//改自第4題
#include <iostream>
using namespace std;
#include <algorithm>

template <class T>
int reduce(T ar[], int n);

int main()
{
    long arr_test[10] = {156, 124, 23, 43, 35, 23, 124, 199, 210, 56};
    cout << "Original array:\n";
    for(int i = 0; i < 10; i++)
        cout << arr_test[i] << " ";
    cout << endl;
    int newsize = reduce(arr_test, 10);//返回縮減後數組中的元素數目
    cout << "Newsize: " << newsize << endl;
    cout << "After reduction, the long array:\n";
    for(int i = 0; i < newsize; i++)
        cout << arr_test[i] << " ";
    cout << endl;

    cout << "The second test array: \n";
    string arr_test2[10] = {"hah", "china", "play", "end", "hah", "play", "speak", "play", "zero", "apple"};
    cout << "Original array:\n";
    for(int i = 0; i < 10; i++)
        cout << arr_test2[i] << " ";
    cout << endl;
    int newsize2 = reduce(arr_test2, 10);//返回縮減後數組中的元素數目
    cout << "Newsize: " << newsize2 << endl;
    cout << "After reduction, the long array:\n";
    for(int i = 0; i < newsize2; i++)
        cout << arr_test2[i] << " ";
    cout << endl;

    return 0;
}

template <class T>
int reduce(T ar[], int n)
{
    sort(ar, ar + n);//排序
    T * arr_new;
    arr_new = unique(ar, ar + n);//去重
    //用unique()函數返回結果區間結尾的特點,將該結尾指針地址賦給一個long指針,將該地址減去實參的數組名地址,即是縮減後的元素數目
    return arr_new - ar;
}

6.

本題要求我們對程序清單12.12進行修改,使用STL queue模板類來代替Queue類。我們可以沿用程序清單12.12的程序框架,把"queue.h"換成<queue>即可。同時將queue.h內聲明的Customer類放在同一個文件中聲明和定義,放棄Queue類,轉而使用queue<Customer>模板類來代替。

所以我們只需要把main()函數裏面的Queue類聲明改爲queue<Customer>類聲明即可.

play.cpp

//改自清單12.12
#include <iostream>
using namespace std;
#include <queue>
#include <cstdlib>
#include <ctime>

class Customer
{
    long arrive;
    int processtime;
public:
    Customer() {arrive = processtime = 0;}
    void set(long when) {processtime = rand()%3 + 1; arrive = when;}
    long when() const { return arrive;}
    int ptime() const { return processtime;}
};


const int MIN_PER_HR = 60;
bool newcustomer(double x);

int main()
{
    srand(time(0));
    cout << "Case Study: Bank of Heather Automatic Teller\n";
    cout << "Enter maximum size of queue: ";
    int qs;
    cin >> qs;
    queue<Customer> line;

    cout << "Enter the number of simulation hours: ";
    int hours;
    cin >> hours;
    long cyclelimit = MIN_PER_HR * hours;

    cout << "Enter the average number of customers per hour: ";
    double perhour;
    cin >> perhour;
    double min_per_cust;
    min_per_cust = MIN_PER_HR / perhour;

    Customer temp;
    long turnaways = 0;
    long customers = 0;
    long served = 0;
    long sum_line = 0;
    int wait_time = 0;
    long line_wait = 0;
    for(int cycle = 0; cycle < cyclelimit; cycle++)
    {
        if(newcustomer(min_per_cust))
        {
            if(qs == line.size())
                turnaways++;
            else
            {
                customers++;
                temp.set(cycle);
                line.push(temp);
            }
        }
        if(wait_time <= 0 && !line.empty())
        {
            temp = line.front();
            wait_time = temp.ptime();
            line_wait += cycle - temp.when();
            served++;
            line.pop();
        }
        if(wait_time > 0)
            wait_time--;
        sum_line += line.size();
    }

    if(customers > 0)
    {
        cout << "customers accepted: " << customers << endl;
        cout << "  customers served: " << served << endl;
        cout << "         turnaways: " << turnaways << endl;
        cout << "average queue size: " ;
        cout.precision(2);
        cout.setf(ios_base::fixed, ios_base::floatfield);
        cout << (double)sum_line / cyclelimit << endl;
        cout << " average wait time: "
        << (double)line_wait / served << " minutes\n";
    }
    else
        cout << "No customers!\n";
    cout << "Done!\n";

    return 0;
}

bool newcustomer(double x)
{
    return (rand() * x / RAND_MAX < 1);
}

7.

play.cpp

#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
vector<int> Lotto(int cnum, int rnum);

int main()
{
    vector<int> winners;
    winners = Lotto(51, 6);
    cout << "Winner's number:\n";
    for(auto i = winners.begin(); i != winners.end(); i++)
        cout << *i << " ";
    cout << endl;

    return 0;
}

vector<int> Lotto(int cnum, int rnum)
{
    vector<int> ticket(cnum);
    for(int i = 0; i < cnum; i++)
        ticket[i] = i + 1;
    random_shuffle(ticket.begin(), ticket.end());
    vector<int> choose(rnum);
    for(int i = 0; i < rnum; i++)
        choose[i] = ticket[i];
    sort(choose.begin(), choose.end());

    return choose;
}

8.

play.cpp

#include <iostream>
using namespace std;
#include <vector>
#include <string>
#include <algorithm>

int main()
{
    vector<string> mat_f, pat_f, total_f;//3個容器
    cout << "Enter Mat's friends(empty line to quit):\n";
    string temp;
    while (getline(cin, temp))
    {
        mat_f.push_back(temp);
        total_f.push_back(temp);
        if(temp[0] == '\0')
            break;
    }
    cout << "The following are Mat's friends:\n";
    sort(mat_f.begin(), mat_f.end());
    for(auto i = mat_f.begin(); i != mat_f.end(); i++)
        cout << *i << endl;
    cout << endl << endl;

    cout << "Enter Pat's friends(empty line to quit):\n";
    while (getline(cin, temp))
    {
        pat_f.push_back(temp);
        total_f.push_back(temp);
        if(temp[0] == '\0')
            break;
    }
    cout << "The following are Pat's friends:\n";
    sort(pat_f.begin(), pat_f.end());
    for(auto i = pat_f.begin(); i != pat_f.end(); i++)
        cout << *i << endl;
    cout << endl << endl;

    sort(total_f.begin(), total_f.end());
    unique(total_f.begin(), total_f.end());
    cout << "There are " << total_f.size() << " friends to be invited in total:\n";
    for(auto i = total_f.begin(); i != total_f.end(); i++)
        cout << *i << endl;
    cout << endl << endl;

    return 0;
}

9.

play.cpp

#include <iostream>
using namespace std;
#include <algorithm>
#include <ctime>
#include <vector>
#include <list>
#include <string>

const int NUM = 10000000;
int main()
{
    cout << "-------begin--------" << endl;
    srand(time(0));
    vector<int> vi0(NUM);
    for(int i = 0; i < NUM; i++)
        vi0[i] = rand();

    vector<int> vi(vi0);//創建vector<int>對象vi和list<int>對象li,它們的長度都和初始值與vi0相同
    list<int> li(vi0.begin(), vi0.end());
    cout << "Measure the sort() algorithm's running time for vector<int>:\n";
    clock_t vector_start = clock();
    sort(vi.begin(), vi.end());
    clock_t vector_end = clock();
    cout << "The time is " << (double)(vector_end - vector_start) / CLOCKS_PER_SEC << "s.\n";

    cout << "Measure the sort() algorithm's running time for list<int>:\n";
    clock_t list_start = clock();
    li.sort();
    clock_t list_end = clock();
    cout << "The time is " << (double)(list_end - list_start) / CLOCKS_PER_SEC << "s.\n";

    cout << "Measure the copy() and sort() algorithm's running time:\n";
    copy(vi0.begin(), vi0.end(), li.begin());//li重置爲排序的vi0的內容
    clock_t copy_start = clock();
    copy(li.begin(), li.end(), vi.begin());//將li的內容複製到vi中
    sort(vi.begin(), vi.end());//對vi進行排序
    copy(vi.begin(), vi.end(), li.begin());//並將結果複製到li中
    clock_t copy_end = clock();
    cout << "The time is " << (double)(copy_end - copy_start) / CLOCKS_PER_SEC << "s.\n";

    return 0;
}

10.

play.cpp

//改自清單16.9
#include <iostream>
using namespace std;
#include <algorithm>
#include <vector>
#include <string>

struct Review
{
    string title;
    int rating;
    double price;
};

//按題,不使用vector<Review>來存儲輸入,而使用vector<shared_ptr<Review>>
bool operator <(const shared_ptr<Review> &r1, const shared_ptr<Review> &r2);
//添加betterthan(),expensivethan(),cheapthan()函數,來讓用戶選擇按評級降序顯示,按價格降序顯示,按價格升序顯示
bool worsethan(const shared_ptr<Review> &r1, const shared_ptr<Review> &r2);
bool betterthan(const shared_ptr<Review> &r1, const shared_ptr<Review> &r2);
bool expensivethan(const shared_ptr<Review> &r1, const shared_ptr<Review> &r2);
bool cheapthan(const shared_ptr<Review> &r1, const shared_ptr<Review> &r2);
bool FillReview(Review &rr);
void ShowReview(const shared_ptr<Review> &rr);

int main()
{
    vector<shared_ptr<Review>> books;
    Review temp;
    while (FillReview(temp))
    {
        shared_ptr<Review> newtemp(new Review(temp));
        books.push_back(newtemp);
    }
    if(books.size() > 0)
    {
        cout << "Thank you. You entered the following "
        << books.size() << " ratings:\n"
        << "Rating\tBook\n";
        for_each(books.begin(), books.end(), ShowReview);

        cout << "Please choose a type to show(0 for original order, 1 for alphabet order, 2 for rating ascend order, \n3 for rating discend order, 4 for price ascend order, 5 for price discend order, q for quit): ";
        int input;
        while (cin >> input)
        {
            switch (input)
            {
                case 0:
                    break;
                case 1:
                    sort(books.begin(), books.end());
                    break;
                case 2:
                    sort(books.begin(), books.end(), worsethan);
                    break;
                case 3:
                    sort(books.begin(), books.end(), betterthan);
                    break;
                case 4:
                    sort(books.begin(), books.end(), cheapthan);
                    break;
                case 5:
                    sort(books.begin(), books.end(), expensivethan);
                    break;
                default:
                    break;
            }
            for_each(books.begin(), books.end(), ShowReview);
            cout << "Please choose a type to show(0 for original order, 1 for alphabet order, 2 for rating ascend order, \n3 for rating discend order, 4 for price ascend order, 5 for price discend order, q for quit): ";
        }

    }
    else
        cout << "No entries. ";
    cout << "Bye.\n";

    return 0;
}

bool operator <(const shared_ptr<Review> &r1, const shared_ptr<Review> &r2)
{
    if(r1->title < r2->title)
        return true;
    else if (r1->title == r2->title && r1->rating < r2->rating)
        return true;
    else
        return false;
}

bool worsethan(const shared_ptr<Review> &r1, const shared_ptr<Review> &r2)
{
    if(r1->rating < r2->rating)
        return true;
    else
        return false;
}

bool betterthan(const shared_ptr<Review> &r1, const shared_ptr<Review> &r2)
{
    if(r1->rating > r2->rating)
        return true;
    else
        return false;
}

bool expensivethan(const shared_ptr<Review> &r1, const shared_ptr<Review> &r2)
{
    if(r1->price > r2->price)
        return true;
    else
        return false;
}

bool cheapthan(const shared_ptr<Review> &r1, const shared_ptr<Review> &r2)
{
    if(r1->price < r2->price)
        return true;
    else
        return false;
}

bool FillReview(Review & rr)
{
    cout << "Enter book title(q to quit): ";
    getline(cin, rr.title);
    if(rr.title == "q")
        return false;
    cout << "Enter book rating: ";
    cin >> rr.rating;
    cout << "Enter book price: ";
    cin >> rr.price;
    if(!cin)
        return false;
    while (cin.get() != '\n')
        continue;
    return true;
}

void ShowReview(const shared_ptr<Review> &rr)
{
    cout << rr->rating << "\t" << rr->price << "\t" << rr->title << endl;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章