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

1.

cow.h

#ifndef COW_H
#define COW_H
class Cow{
    char name[20];
    char * hobby;
    double weight;
public:
    Cow();
    Cow(const char * nm, const char * ho, double wt);
    Cow(const Cow & c);
    ~Cow();
    Cow &operator=(const Cow & c);
    void Showcow() const;
};

#endif

cow.cpp

#include "cow.h"
#include <iostream>
using namespace std;
#include <cstring>

Cow::Cow()
{
    strcpy_s(name, 20, "new cow");
    hobby = new char[4];
    strcpy_s(hobby, 4, "cow");
    weight = 0.0;
}

Cow::Cow(const char *nm, const char *ho, double wt)
{
    weight = wt;
    hobby = new char[strlen(ho) + 1];
    strcpy_s(hobby, strlen(ho) + 1, ho);
    strcpy_s(name, 20, nm);
}

Cow::Cow(const Cow &c)
{
    strcpy_s(name, 20, c.name);
    hobby = new char[strlen(c.hobby) + 1];;
    strcpy_s(hobby, strlen(c.hobby) + 1, c.hobby);
    weight = c.weight;
}

Cow::~Cow()
{
    delete [] hobby;
}

Cow & Cow::operator=(const Cow & c)
{
    delete [] hobby;
    hobby = new char[strlen(c.hobby) + 1];
    strcpy_s(hobby, strlen(c.hobby) + 1, c.hobby);
    weight = c.weight;
    strcpy_s(name, 20, c.name);
    return *this;
}

void Cow::Showcow() const
{
    cout << "Now a new cow!\n";
    cout << "The name is " << name << endl;
    cout << "The hobby is " << hobby << endl;
    cout << "The weight is " << weight << endl;
}

play.cpp

#include "cow.h"
#include <iostream>
using namespace std;
int main()
{
    cout << "See cows!\n";
    Cow c1;
    c1.Showcow();
    Cow c2("A", "aaaa", 111.111);
    c2.Showcow();
    Cow c3("B", "bbbb", 222.222);
    c3.Showcow();
    c3 = c1;
    Cow c4(c2);
    c3.Showcow();
    c4.Showcow();

    return 0;
}

 

2.暫

3.

stock20.h

//改自清單10.7
#ifndef STOCK20_H
#define STOCK20_H
#include <iostream>
using namespace std;
class Stock{
    char * company;//要求用動態內存分配代替string類對象,所以string對象company必須改爲char *類型
    int shares;
    double share_val;
    double total_val;
    void set_tot() {total_val = shares * share_val};
public:
    Stock();
    Stock(const char * co, long n = 0, double pr = 0.0);
    ~Stock();
    void buy(long num, double price);
    void sell(long num, double price);
    void update(double price);
    friend ostream & operator<<(ostream &os, const Stock &st);//要求用重載的operator<<()定義代替show()成員函數
    const Stock & topval(const Stock & s) const;
};

#endif

stock20.cpp

//改自清單10.8
#include "stock20.h"
#include <iostream>
using namespace std;

Stock::Stock()
{
    company = new char[strlen("no name") + 1];
    strcpy_s(company, strlen("no name") + 1, "no name");//對應string下的company="no name"

    shares = 0;
    share_val = 0.0;
    total_val = 0.0;
}

Stock::Stock(const char *co, long n, double pr)
{
    company = new char [strlen(co) + 1];
    strcpy_s(company, strlen(co) + 1, co);
    if(n < 0)
    {
        cout << "Number of shares can't be negative; "
             << company << " sahres set to 0.\n";
        shares = 0;
    }
    else
        shares = n;
    share_val = pr;
    set_tot();
}

Stock::~Stock()
{
    delete [] company;
}

void Stock::buy(long num, double price)
{
    if(num < 0)
        cout << "Number of shares purchased can't be negative. "
             << "Transaction is aborted.\n";
    else
    {
        shares += num;
        share_val = price;
        set_tot();
    }
}

void Stock::sell(long num, double price)
{
    if(num < 0)
        cout << "Number of shares sold can't be negative. "
             << "Transaction is aborted.\n";
    else if (num > shares)
        cout << "You can't sell more than you have! "
        << "Transaction is aborted.\n";
    else
    {
        shares -= num;
        share_val = price;
        set_tot();
    }
}

void Stock::update(double price)
{
    share_val = price;
    set_tot();
}

ostream & operator<<(ostream &os, const Stock &st)
{
    ios_base::fmtflags orig = cout.setf(ios_base::fixed, ios_base::floatfield);
    streamsize prec = cout.precision(3);

    cout << "Company: " << st.company << " Shares: " << st.shares << endl;
    cout << " Share Price: $" << st.share_val;
    cout.precision(2);
    cout << " Total Worth: $" << st.total_val << endl;
    cout.setf(orig, ios_base::floatfield);
    cout.precision(prec);
    return os;
}

const Stock & Stock::topval(const Stock & s) const
{
    if(s.total_val > total_val)
        return s;
    else
        return *this;
}

play.cpp

//清單10.9
#include <iostream>
#include "stock20.h"
const int STKS = 4;
int main()
{
    Stock stocks[STKS] = {
            Stock("NanoSmart", 12, 20.0),
            Stock("Boffo Objects", 200, 2.0),
            Stock("Monolithic Obelisks", 130, 3.25),
            Stock("Fleep Enterprises", 60, 6.5)
    };
    cout << "Stock holdings:\n";
    int st;
    for(st = 0; st < STKS; st++)
        cout << stocks[st];
    const Stock * top = &stocks[0];
    for(st = 1; st < STKS; st++)
        top = &top->topval(stocks[st]);
    cout << "\nMost valuable holding:\n";
    cout << *top;

    return 0;
}

4.暫

5.

queue.h

//清單12.10
#ifndef QUEUE_H
#define QUEUE_H
class Customer{
    long arrive;
    int processtime;
public:
    Customer() {arrive = processtime = 0;}
    void set(long when);
    long when() const { return arrive;}
    int ptime() const { return processtime;}

};
typedef Customer Item;
class Queue{
    struct Node{
        Item item;
        struct Node * next;
    };
    enum {Q_SIZE = 10};
    Node * front;
    Node * rear;
    int items;
    const int qsize;
    Queue(const Queue & q) : qsize(0) {}
    Queue &operator=(const Queue & q) { return *this;}
public:
    Queue(int qs = Q_SIZE);
    ~Queue();
    bool isempty() const ;
    bool isfull() const ;
    int queuecount() const ;
    bool enqueque(const Item &item);
    bool dequeue(Item &item);
};

#endif

queue.cpp

//清單12.11
#include "queue.h"
#include <iostream>
using namespace std;
#include <cstdlib>

Queue::Queue(int qs) : qsize(qs)
{
    front = rear = NULL;
    items = 0;
}

Queue::~Queue()
{
    Node * temp;
    while (front != NULL)
    {
        temp = front;
        front = front->next;
        delete temp;
    }
}

bool Queue::isempty() const
{
    return items == 0;
}

bool Queue::isfull() const
{
    return items == qsize;
}

int Queue::queuecount() const
{
    return items;
}

bool Queue::enqueque(const Item & item)
{
    if(isfull())
        return false;
    Node * add = new Node;
    add->item = item;
    add->next = NULL;
    items ++;
    if(front == NULL)
        front = add;
    else
        rear->next = add;
    rear = add;
    return true;
}

bool Queue::dequeue(Item & item)
{
    if(front == NULL)
        return false;
    item = front->item;
    items--;
    Node * temp = front;
    front = front->next;
    delete temp;
    if(items == 0)
        rear = NULL;
    return true;
}

void Customer::set(long when)
{
    processtime = rand() % 3 + 1;
    arrive = when;
}

play.cpp

//改自清單12.12
#include <iostream>
#include "queue.h"
using namespace std;
#include <ctime>
#include <cstdlib>
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 line(qs);

    cout << "The simulation hour: 100" << endl;
    int hours = 100;
    long cyclelimit = MIN_PER_HR * hours;

    double perhour;
    double min_per_cust;
    perhour = 1;

    Item temp;
    long turnaways = 0;
    long customers = 0;
    long served = 0;
    long sum_line = 0;
    int wait_time = 0;
    long line_wait = 0;
    double avetime = 0;
    while (perhour++ && avetime<= 1)
    {
        while (!line.isempty())
            line.dequeue(temp);
        min_per_cust = MIN_PER_HR / perhour;

        for(int cycle=0; cycle < cyclelimit; cycle++)
        {
            if(newcustomer(min_per_cust))
            {
                if(line.isfull())
                    turnaways++;
                else
                {
                    customers++;
                    temp.set(cycle);
                    line.enqueque(temp);
                }
            }
            if(wait_time <= 0 && !line.isempty())
            {
                line.dequeue(temp);
                wait_time = temp.ptime();
                line_wait += cycle - temp.when();
                served++ ;
            }
            if(wait_time > 0)
                wait_time--;
            sum_line += line.queuecount();
        }

        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";
        avetime = (double)line_wait / served;

    }
    cout << "When there comes " << perhour << " people per hour, the average wait time will be about 1 minute.\n";
    cout << "Done!\n";

    return 0;
}

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

6.

本題要求多開設一個ATM,所以我們就會有兩個隊列,一起進行服務,客戶到達之後的排隊方式即是,如果第一臺人數少於第二臺,則排第一隊,否則排第二隊。所以相比第5題,頭文件和實現文件依然不變,因爲本質性功能依然沒變,只需更改檢驗文件。

play.cpp

//改自清單12.12
#include <iostream>
#include "queue.h"
using namespace std;
#include <ctime>
#include <cstdlib>
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 line1(qs);
    Queue line2(qs);

    cout << "The simulation hour: 100" << endl;
    int hours = 100;
    long cyclelimit = MIN_PER_HR * hours;

    double perhour;
    double min_per_cust;
    perhour = 1;

    Item temp;
    long turnaways = 0;
    long customers = 0;
    long served = 0;
    long sum_line = 0;
    int wait_time1 = 0;
    int wait_time2 = 0;
    int line1_size = 0;
    int line2_size = 0;
    long line_wait = 0;
    double avetime = 0;

    while (perhour++ && avetime<= 1)
    {
        while (!line1.isempty())
            line1.dequeue(temp);
        while (!line2.isempty())
            line2.dequeue(temp);
        min_per_cust = MIN_PER_HR / perhour;

        for(int cycle=0; cycle < cyclelimit; cycle++)
        {
            if(newcustomer(min_per_cust))
            {
                if(line1.isfull() && line2.isfull())
                    turnaways++;
                else if (line1_size < line2_size)
                {
                    customers++;
                    temp.set(cycle);
                    line1.enqueque(temp);
                    line1_size++;
                }
                else
                {
                    customers++;
                    temp.set(cycle);
                    line2.enqueque(temp);
                    line2_size++;
                }
            }
            if(wait_time1 <= 0 && !line1.isempty())
            {
                line1.dequeue(temp);
                line1_size--;
                wait_time1 = temp.ptime();
                line_wait += cycle - temp.when();
                served++ ;
            }
            if(wait_time2 <= 0 && !line2.isempty())
            {
                line2.dequeue(temp);
                line2_size--;
                wait_time2 = temp.ptime();
                line_wait += cycle - temp.when();
                served++ ;
            }
            if(wait_time1 > 0)
                wait_time1--;
            if(wait_time2 > 0)
                wait_time2--;
            sum_line += line1.queuecount();
            sum_line += line2.queuecount();
        }

        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";
        avetime = (double)line_wait / served;

    }
    cout << "When there comes " << perhour << " people per hour, the average wait time will be about 1 minute.\n";
    cout << "Done!\n";

    return 0;
}

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

從結果上可以看出,當只有1臺ATM時,每小時到達客戶數爲25時,平均等候時間爲1分鐘,而兩臺ATM時,每小時到達客戶數爲60,平均等候時間爲1分鐘,所以效果不止翻倍。 

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