C++ Primer Plus 第六版第十二章编程练习答案

//question1

 

//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 <cstring>
#include <iostream>
#include "Cow.h"

Cow::Cow()
{
    name[0] = '\0';
    hobby = new char[1];
    hobby[0] = '\0';
    weight = 0;
}

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

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

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

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

void Cow::ShowCow() const
{
    std::cout << "name: " << name << std::endl;
    std::cout << "hobby: " << hobby << std::endl;
    std::cout << "weight: " << weight << std::endl;
}

//12_1.cpp
#include "Cow.h"

int main()
{
    Cow a;
    Cow b("xyz", "music", 24);
    Cow c(b);
    a.ShowCow();
    b.ShowCow();
    c.ShowCow();
    a = c;
    a.ShowCow();
    return 0;
}

 

//question2

//String2.h
#ifndef STRING2_H
#define STRING2_H
#include <iostream>
using std::ostream;
using std::istream;

class String
{
    private:
        char * str;
        int len;
        static int num_strings;
        static const int CINLIM = 80;
    public:
        String(const char * s);
        String();
        String(const String &);
        ~String();
        int length() const {return len;}
        String & operator=(const String &);
        String & operator=(const char *);
        char & operator[](int i);
        const char & operator[](int i) const;
        friend bool operator<(const String &st1, const String &st2);
        friend bool operator>(const String &st1, const String &st2);
        friend bool operator==(const String &st1, const String &st2);
        friend String operator+(const String &st1, const String &st2);
        friend ostream & operator<<(ostream & os, const String &st);
        friend istream & operator>>(istream & is, String & st);
        static int HowMany();
        void stringlow();
        void stringup();
        int has(char a) const;
};
#endif

//String2.cpp
#include <cstring>
#include <cctype>
#include "String2.h"
using std::cin;
using std::cout;

int String::num_strings = 0;

int String::HowMany()
{
    return num_strings;
}

String::String(const char * s)
{
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str, s);
    num_strings++;
}

String::String()
{
    len = 0;
    str = new char[1];
    str[0] = '\0';
    num_strings++;
}

String::String(const String & st)
{
    num_strings++;
    len = st.len;
    str = new char [len + 1];
    std::strcpy(str, st.str);

String::~String()
{
    --num_strings;
    delete [] str;
}

String & String::operator=(const String & st)
{
    if (this == & st)
        return *this;
    delete [] str;
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str, st.str);
    return *this;
}

String & String::operator=(const char * s)
{
    delete [] str;
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str, s);
    return *this;
}

char & String::operator[](int i)
{
    return str[i];
}

const char & String::operator[](int i) const
{
    return str[i];
}

bool operator<(const String &st1, const String &st2)
{
    return (std::strcmp(st1.str, st2.str) < 0);
}

bool operator>(const String &st1, const String &st2)
{
    return st2 < st1;
}

bool operator==(const String &st1, const String &st2)
{
    return (std::strcmp(st1.str, st2.str) == 0);
}

ostream & operator<<(ostream & os, const String &st)
{
    os << st.str;
    return os;
}

istream & operator>>(istream & is, String & st)
{
    char temp[String::CINLIM];
    is.get(temp, String::CINLIM);
    if (is)
        st = temp;
    while (is && is.get() != '\n')
        continue;
    return is;
}

String operator+(const String &st1, const String &st2)
{
    char temp[st1.len + 1];
    strcpy(temp, st1.str);
    strcat(temp, st2.str);
    return String(temp);
}

void String::stringup()
{
    for (int i = 0; i < len; i++)
    {
        if (islower(str[i])) str[i] = toupper(str[i]);
    }
}

void String::stringlow()
{
    for (int i = 0; i < len; i++)
    {
        if (isupper(str[i])) str[i] = tolower(str[i]);
    }
}

int String::has(char a) const
{
    int count = 0;
    for (int i = 0; i < len; i++)
    {
        if (str[i] == a) count++;
    }
    return count;
}

//12_2.cpp
#include <iostream>
using namespace std;
#include "String2.h"

int main()
{
    String s1(" and I am a C++ student.");
    String s2 = "Please enter your name: ";
    String s3;
    cout << s2;
    cin >> s3;
    s2 = "My name is " + s3;
    cout << s2 << ".\n";
    s2 = s2 + s1;
    s2.stringup();
    cout << "The string\n" << s2 << "\ncontains " << s2.has('A')
         << " 'A' characters in it.\n";
    s1 = "red";
    String rgb[3] = {String(s1), String("green"), String("blue")};
    cout << "Enter the name of a primary color for mixing light: ";
    String ans;
    bool success = false;
    while (cin >> ans)
    {
        ans.stringlow();
        for (int i = 0; i < 3; i++)
        {
            if (ans == rgb[i])
            {
                cout << "That's right!\n";
                success = true;
                break;
            }
        }
        if (success)
            break;
        else
            cout << "Try again!\n";
    } 
    cout << "Bye\n";
    return 0; 
}

 

//question3

//stock.h
#ifndef STOCK_H
#define STOCK_H
#include <iostream> 

class Stock
{
    private:
        char * company;
        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 std::ostream & operator<<(std::ostream & os, const Stock & a);
        const Stock & topval(const Stock & s) const;
};
#endif

//stock.cpp
#include <iostream>
#include <cstring>
#include "stock.h"

Stock::Stock()
{
    company = new char[8];
    strcpy(company, "no name");
    company[7] = '\0';
    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(company, co);
    if (n < 0)
    {
        std::cout << "Number of shares can't be negative;"
                  << company << " shares 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)
    {
        std::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)
{
    using std::cout;
    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();
}

std::ostream & operator<<(std::ostream & os, const Stock & a)
{
    using std::ios_base;
    ios_base::fmtflags orig = os.setf(ios_base::fixed, ios_base::floatfield);
    std::streamsize prec = os.precision(3);
    
    os << "Company: " << a.company
       << " Shares: " << a.shares << '\n';
    os << " Share Price: $" << a.share_val;
    
    os.precision(2);
    os << " Total Worth: $" << a.total_val << '\n';
    os.setf(orig, ios_base::floatfield);
    os.precision(prec);
    return os;
}

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

//12_3.cpp
#include <iostream>
#include "stock.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)
        };
    std::cout << "Stock holdings:\n";
    int st;
    for (st = 0; st < STKS; st++)
        std::cout << stocks[st];
    const Stock * top = &stocks[0];
    for (st = 1; st < STKS; st++)
        top = &top->topval(stocks[st]);
    std::cout << "\nMost valuable holding:\n";
    std::cout << *top;
    return 0; 

 

//question4

纠结这道题很久,觉得题目有些问题,如果用动态内存方式来实现栈,那么难免构造函数new Item[n] 之后在push 中会有越界现象,这是我的想法,所以就正常实现了一下栈。

//stack.h
typedef unsigned long Item;

class Stack
{
    private:
        enum {MAX = 10};
        Item pitems[MAX];
        int size;
        int top;
    public:
        Stack(int n = MAX);
        Stack(const Stack & st);
        ~Stack();
        bool isempty() const;
        bool isfull() const;
        bool push(const Item & item);
        bool pop(Item & item);
        Stack & operator=(const Stack & st);
        void show() const;
};

//stack.cpp
#include <iostream>
#include "stack.h"

Stack::Stack(int n)
{
    if (n > MAX || n < 0)
    {
        std::cout << "Wrong! Set n to MAX\n";
        size = MAX;
        top = MAX - 1;
    } 
    else
    {
        size = n;
        top = n - 1;
    }
    std::cout << "Enter members: \n";
    for (int i = 0; i < size; i++)
    {
        std::cout << i+1 << ": ";
        std::cin >> pitems[i];
    }
}

Stack::Stack(const Stack & st)
{
    for (int i = 0; i < st.size; i++)
        pitems[i] = st.pitems[i];
    size = st.size;
    top = st.top;
}

Stack::~Stack()
{
}

bool Stack::isempty() const
{
    return size == 0;
}

bool Stack::isfull() const
{
    return size == MAX;
}

bool Stack::push(const Item & item)
{
    if (isfull())
        return false;
    else
    {
        size++;
        top++;
        pitems[top] = item;
        return true;
    }
}

bool Stack::pop(Item & item)
{
    if (isempty())
        return false;
    else
    {
        size--;
        item = pitems[top];
        top--;
        return true;
    }
}

Stack & Stack::operator=(const Stack & st)
{
    if (this == &st)
        return *this;
    for (int i = 0; i < st.size; i++)
        pitems[i] = st.pitems[i];
    size = st.size;
    top = st.top;
}

void Stack::show() const
{
    for (int i = 0; i < size; i++)
    {
        std::cout << pitems[i] << " ";
    }
    std::cout << "\n";
}

//12_4.cpp
#include <iostream>
#include "stack.h"

int main()
{
    Stack a(5);
    Stack b(a);
    a.show();
    b.show();
    Item item, item2;
    std::cout << "Enter a mem:";
    std::cin >> item;
    if (a.push(item)) a.show();
    b = a;
    b.show();
    if (b.pop(item2)) std::cout << "pop: " << item2 << "\n";
    b.show();
    if (b.pop(item2)) std::cout << "pop: " << item2 << "\n";
    b.show();
    if (b.pop(item2)) std::cout << "pop: " << item2 << "\n";
    b.show();
    if (b.pop(item2)) std::cout << "pop: " << item2 << "\n";
    b.show();
    if (b.pop(item2)) std::cout << "pop: " << item2 << "\n";
    b.show();
    return 0;
}

 

//question5

//queue.h
#ifndef QUEUE_H
#define QUEUE_H

class Customer
{
    private:
        long arrive;
        int processtime;
    public:
        Customer();
        void set(long when);
        long when() const {return arrive;}
        int ptime() const {return processtime;}
};

typedef Customer Item;

class Queue
{
    private:
        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 enqueue(const Item & item);
        bool dequeue(Item & item);
};
#endif

//queue.cpp
#include "queue.h"
#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::enqueue(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 = std::rand() % 3 + 1;
    arrive = when;

Customer::Customer()
{
    arrive = processtime = 0;
}

//12_5.cpp

//12_5.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "queue.h"

const int MIN_PER_HR = 60;

bool newcustomer(double x);

int main()
{
    using std::cin;
    using std::cout;
    using std::endl;
    using std::ios_base;
    std::srand(std::time(0));
    
    cout << "Case Study: Bank of Heather Automatic Teller\n";
    cout << "Enter maximum size of queue: ";
    int qs;
    cin >> qs;
    int hours = 100;
    long cyclelimit = MIN_PER_HR * hours;
    cout << "Enter the average number of customers per hour(to start): ";
    double perhour;
    cin >> perhour;
    double min_per_cust;
    min_per_cust = MIN_PER_HR / perhour;
    cout << "Enter the max simulate times: ";
    int simulate;
    cin >> simulate;
    
    Item temp;
    long turnaways = 0;
    long customers = 0;
    long served = 0;
    long sum_line = 0;
    int wait_time = 0;
    long line_wait = 0;
    double avr_wait = 0;
    int i = 0;
    
    for (i = 0; i < simulate; i++)
    {
        turnaways = 0;
        customers = 0;
        served = 0;
        sum_line = 0;
        wait_time = 0;
        line_wait = 0;
        avr_wait = 0;
        Queue line(qs);
        for (int cycle = 0; cycle < cyclelimit; cycle++)
        {
            if (newcustomer(min_per_cust))
            {
                if (line.isfull())
                    turnaways++;
                else
                {
                    customers++;
                    temp.set(cycle);
                    line.enqueue(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();
        }
        avr_wait = (double) line_wait / served;
        cout << "simulation " << i+1 << ": perhour customer: " << perhour
             << ", avr_wait " << avr_wait << "minutes.\n";     
        if (avr_wait <= 1.05 && avr_wait >= 0.95)
            break;
        else if(avr_wait > 1.05)
            perhour--;
        else
            perhour++;
        min_per_cust = MIN_PER_HR / perhour; 
    }
    if (i == simulate)
        cout << "Not finished. Need more simulation.";
    else
    {
        cout << "Everage " << perhour << " customers per hour " << " can make average wait time "
             << " becomes " << avr_wait << " minutes.";
    }
    return 0;
}

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

 

 

//question6

 

//12_6.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "queue.h"

const int MIN_PER_HR = 60;

bool newcustomer(double x);

int main()
{
    using std::cin;
    using std::cout;
    using std::endl;
    using std::ios_base;
    std::srand(std::time(0));
    
    cout << "Case Study: Bank of Heather Automatic Teller\n";
    cout << "Enter maximum size of queue: ";
    int qs;
    cin >> qs;
    int hours = 100;
    long cyclelimit = MIN_PER_HR * hours;
    cout << "Enter the average number of customers per hour(to start): ";
    double perhour;
    cin >> perhour;
    double min_per_cust;
    min_per_cust = MIN_PER_HR / perhour;
    cout << "Enter the max simulate times: ";
    int simulate;
    cin >> simulate;
    
    Item temp;
    int i = 0;
    long turnaways = 0;
    long customers = 0;
    long served = 0;
    long sum_line = 0;
    int wait_time1 = 0;
    int wait_time2 = 0;
    long line_wait = 0;
    double avr_wait = 0;
    for (i = 0; i < simulate; i++)
    {
        turnaways = 0;
        customers = 0;
        served = 0;
        sum_line = 0;
        wait_time1 = 0;
        wait_time2 = 0;
        line_wait = 0;
        avr_wait = 0;
        
        Queue line1(qs);
        Queue line2(qs);
        for (int cycle = 0; cycle < cyclelimit; cycle++)
        {
            if (newcustomer(min_per_cust))
            {
                if (line1.isfull() && line2.isfull())
                    turnaways++;
                else if (line1.queuecount() > line2.queuecount())
                {
                    customers++;
                    temp.set(cycle);
                    line2.enqueue(temp);
                }
                else
                {
                    customers++;
                    temp.set(cycle);
                    line1.enqueue(temp);
                }
            }
                if ( wait_time1 <= 0 && !line1.isempty())
                {
                    line1.dequeue(temp);
                    wait_time1 = temp.ptime();
                    line_wait += cycle - temp.when();
                    served++;
                }
                if (wait_time1 > 0)
                    wait_time1--;
                sum_line += line1.queuecount();
                if ( wait_time2 <= 0 && !line2.isempty())
                {
                    line2.dequeue(temp);
                    wait_time2 = temp.ptime();
                    line_wait += cycle - temp.when();
                    served++;
                }
                if (wait_time2 > 0)
                    wait_time2--;
                sum_line += line2.queuecount();
        }
        cout << line_wait << endl;
        avr_wait = (double) line_wait / served;
        cout << "simulation " << i+1 << ": perhour customer: " << perhour
             << ", avr_wait " << avr_wait << "minutes.\n";  
        if (avr_wait <= 1.0)
            break;
        else
        {
            perhour--;
            min_per_cust = MIN_PER_HR / perhour;  
        }
    }
    if (i == simulate)
        cout << "Not finished. Need more simulation.";
    else
    {
        cout << "Everage " << perhour << " customers per hour " << " can make average wait time "
             << " becomes " << avr_wait << " minutes.";
    }
    return 0;
}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值