C++PrimerPlus中文第六版第12章编程练习答案

1、

// cow.h


#ifndef COW_H_
#define COW_H_

#include<iostream>

class Cow
{
private:
    char name[20];
    char* hobby;
    double weight;
public:
    Cow();
    Cow(const char* nm, const char* hb, double wt);
    Cow(const Cow& c);
    ~Cow();
    Cow& operator=(const Cow& c);
    void ShowCow() const;
};

#endif
// cow.cpp

#include<iostream>
#include"cow.h"

Cow::Cow()
{
    name[0] = '\0';
    hobby = nullptr;
    weight = 0.0;
}

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

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

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

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

void Cow::ShowCow() const
{
    using std::cout;
    using std::endl;
    if (name[0] == '\0')
        cout << "Name is empty,\n";
    else
        cout << "Name: " << name << endl;
    if (hobby == nullptr)
        cout << "Hobby is NULL.\n";
    else
        cout << "Hobby: " << hobby << endl;
    cout << "Weight: " << weight << endl;
}
#include<iostream>
#include"cow.h"

int main()
{
    Cow c1;
    c1.ShowCow();
    Cow c2("cow2", "grass", 100.0);
    c2.ShowCow();
    Cow c3 = c2;
    c3.ShowCow();
    Cow c4;
    c4 = c3;
    c4.ShowCow();
    return 0;
}

2、

// string.h

#ifndef STRING_H_
#define STRING_H_

#include<iostream>

class String
{
private:
    char* str;
    int len;
    static int num_strings;
    static const int CINLIM = 80;
public:
    String();
    String(const char* s);
    String(const String& s);
    ~String();
    friend bool operator<(const String& s1, const String& s2);
    friend bool operator>(const String& s1, const String& s2) { return s2 < s1; };
    friend bool operator==(const String& s1, const String& s2);

    // 习题新增功能
    friend String operator+(const String& s1, const String& s2); // 拼接两个字符串
    void Stringlow(); // 转换成小写
    void Stringup(); // 转换成大写
    int chartimes(const char& ch); // 统计字符ch在字符串中出现的次数


    friend std::ostream& operator<<(std::ostream& os, const String& s);
    friend std::istream& operator>>(std::istream& is, String& s);

    String& operator=(const String& s); // 赋值运算符必须显示定义
    String& operator=(const char* s); // 字符串赋值给类对象
    char& operator[](int i);
    const char& operator[](int i) const;

    int length() { return len; }

    static int HowMany(); //静态成员函数
};

#endif
// string.cpp

#pragma warning(disable : 4996)

#include<iostream>
#include<string>
#include"String.h"

int String::num_strings = 0; // 初始化静态数据成员

// 静态成员函数只能访问静态数据成员,对类的私有成员不能访问
int String::HowMany()
{
    return num_strings;
}

String::String() // 默认构造函数
{
    len = 0;
    str = nullptr;
    num_strings++;
}

String::String(const char* s) //带一个参数的构造函数
{
    len = strlen(s);
    str = new char[len + 1];
    strcpy_s(str, len + 1, s);
    num_strings++;
}

String::String(const String& s) // 复制构造函数
{
    len = strlen(s.str);
    str = new char[len + 1];
    strcpy_s(str, len + 1, s.str);
    num_strings++;
}

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

// 关系运算符
bool operator<(const String& s1, const String& s2)
{
    return strcmp(s1.str, s2.str) < 0;
}
bool operator==(const String& s1, const String& s2)
{
    return strcmp(s1.str, s2.str) == 0;
}

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

// 赋值运算符
String& String::operator=(const String& s)
{
    if (this == &s)
        return *this;
    delete[] str;
    len = strlen(s.str);
    str = new char[len + 1];
    strcpy_s(str, len + 1, s.str);
    return *this;
}
// 重载赋值运算符
String& String::operator=(const char* s)
{
    delete[] str;
    len = strlen(s);
    str = new char[len + 1];
    strcpy_s(str, len + 1, s);
    return *this;
}


// 输入输出运算符重载
std::ostream& operator<<(std::ostream& os, const String& s)
{
    os << s.str;
    return os;
}
std::istream& operator>>(std::istream& is, String& s)
{
    char temp[String::CINLIM];
    is.get(temp, String::CINLIM);
    if (is)
        s = temp;
    while (is && is.get() != '\n')
        continue;
    return is;
}


// 习题新增加的功能
String operator+(const String& s1, const String& s2)
{
    int len = s1.len + s2.len;
    char* str = new char[len + 1];
    strcpy_s(str, len+1, s1.str);
    strcat_s(str, len+1, s2.str);
    String temp(str);
    delete[] str;
    return temp;
}

void String::Stringlow()
{
    strlwr(this->str);
}
void String::Stringup()
{
    strupr(this->str);
}
int String::chartimes(const char& ch)
{
    int times = 0;
    for (int i = 0; i < len; i++)
        if (ch == str[i])
            times++;
    return times;
}
#pragma warning(disable : 4996)
#include<iostream>
#include"string.h"
using namespace std;
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.chartimes('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";
        }
    }

    return 0;
}

3、

// 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, 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& s);
    const Stock& topval(const Stock& s) const;

};

#endif
// stock.cpp

#include<iostream>
#include"stock.h"

Stock::Stock()
{
    company = nullptr;
    shares = 0;
    share_val = 0.0;
    total_val = 0.0;
}

Stock::Stock(const char* co, long n, double pr)
{
    int len = strlen(co);
    company = new char[len + 1];
    strcpy_s(company, len + 1, co);
    shares = std::max(n, long(0)); // shares can't be negative.
    share_val = std::max(pr, double(0.0)); // share_val can't be negative, either.
    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 negaive. Transaction is aborted.\n";
    else if (price < 0)
        std::cout << "Shares value 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 << "Numbers 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 if (price < 0)
        cout << "Value of shares sold can't be negative. Transaction is aborted.\n";
    else
    {
        shares -= num;
        share_val = price;
        set_tot();
    }
}

void Stock::update(double price)
{
    if (price < 0)
        std::cout << "Shares price can't be negative. Failure of Updating Operation.\n";
    else
    {
        share_val = price;
        set_tot();
    }
}

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

    os << "Company: " << s.company << ", Shares: " << s.shares << std::endl;
    os << "Share Price: $" << s.share_val;
    os.precision(2);
    os << ", Total Worth: $" << s.total_val << std::endl;

    os.setf(orig, ios_base::floatfield);
    os.precision(prec);
    return os;
}


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

main函数省略了懒得测试

4、

// stack.h


#ifndef STACK_H_
#define STACK_H_

#include<iostream>


typedef unsigned long Item;

class Stack
{
private:
    static const int MAX = 10;
    Item* pitems;
    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);
    friend std::ostream& operator<<(std::ostream& os, const Stack& st);
};

#endif
// stack.cpp


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

Stack::Stack(int n)
{
    if (n == 0)
        pitems = nullptr;
    else
        pitems = new Item[n];
    size = n;
    top = 0;
}

Stack::Stack(const Stack& st)
{
    int len;
    if (st.pitems == nullptr)
    {
        len = 0;
        pitems = nullptr;
    }        
    else
    {
        len = _msize(st.pitems) / sizeof(Item); // _msize()函数获取动态申请内存的数组空间大小
        pitems = new Item[len];
    }
    for (int i = 0; i < len; i++)
        pitems[i] = st.pitems[i];
    size = len;
    top = st.top;
}

Stack::~Stack()
{
    delete[] pitems;
}

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

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

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


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

Stack& Stack::operator=(const Stack& st)
{
    if (this == &st)
        return *this;
    int len;
    if (st.pitems == nullptr)
    {
        len = 0;
        pitems = nullptr;
    }
    else
    {
        len = _msize(st.pitems) / sizeof(Item); // _msize()函数获取动态申请内存的数组空间大小
        pitems = new Item[len];
    }
    for (int i = 0; i < len; i++)
        pitems[i] = st.pitems[i];
    size = len;
    top = st.top;
    return *this;
}

std::ostream& operator<<(std::ostream& os, const Stack& st)
{
    using std::endl;
    for (int i = 0; i < st.top; i++)
        os << st.pitems[i] << ", ";
    os << endl;
    os << "size: " << st.size << endl;
    os << "top: " << st.top << endl;
    return os;
}
#include<iostream>
#include"stack.h"


int main()
{
    using namespace std;
    Stack st;
    char ch;
    unsigned long po;
    cout << "Please enter A to add a purchase order, P to process a purchase order, and Q to quit.\n";

    while (cin >> ch and toupper(ch) != 'Q')
    {
        while (cin.get() != '\n')
            continue;
        if (!isalpha(ch))
        {
            cout << '\a';
            continue;
        }
        switch (ch)
        {
        case 'A':
        case 'a':    cout << "Enter a purchased order to add: ";
            cin >> po;
            if (st.isfull())
            {
                cout << "stack is already full.\n";
            }
            else
                st.push(po);
            break;
        case 'p':
        case 'P':    if (st.isempty())
        {
            cout << "stack is already empty.\n";
        }
                else
        {
            st.pop(po);
            cout << "purchaes order #" << po << " poped.\n";
        }
                break;
        }

        cout << "Please enter A to add a purchase order, P to process a purchase order, and Q to quit.\n";
    }

    Stack st1 = st;
    cout << st1 << endl;
    Stack st2;
    st2 = st;
    cout << st2 << endl;
}

5、略

6、

// queue.h

#ifndef QUEUE_H_
#define QUEUE_H_


class Customer
{
private:
    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
{
private:
    struct Node
    {
        Item item;
        Node* next;
    };
    static const int Q_SIZE = 10;
    Node* front;
    Node* rear;
    int items;
    const int qsize;


public:
    Queue(int qs = Q_SIZE);
    ~Queue();
    Queue(const Queue& q);
    Queue& operator=(const Queue& q);
    bool isempty() const;
    bool isfull() const;
    int queuecount(); // 队列元素个数
    bool enqueue(const Item& item);
    bool dequeue(Item& item);
};

#endif
// queue.cpp

#include<cstdlib>
#include"queue.h"

void Customer::set(long when)
{
    arrive = when;
    processtime = rand() % 3 + 1; // 客户交易时间随机为1,2,3分钟
}

Queue::Queue(int qs) : qsize(qs) // 成员初始化列表,在类对象创建之前,也就是给数据成员分配内存之前进行数据成员的初始化
{
    front = rear = nullptr;
    items = 0;
}

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

Queue::Queue(const Queue& q) : qsize(q.qsize) // 重定义复制构造函数
{
    items = q.items;
    if (items == 0)
    {
        front = rear = nullptr;
    }
    else
    {
        Node* p = q.front;
        Node* temp = new Node;
        temp->item = p->item;
        front = temp;
        while (p->next != NULL and p != rear)
        {
            p = p->next;
            Node* temp1 = new Node;
            temp1->item = p->item;
            temp->next = temp1;
            temp = temp->next;
        }
        temp->next = nullptr;
        rear = temp;
    }
}


Queue& Queue::operator=(const Queue& q) // 重载赋值运算符
{
    if (this == &q)
        return *this;

    items = q.items;
    if (items == 0)
    {
        front = rear = nullptr;
    }
    else
    {
        Node* p = q.front;
        Node* temp = new Node;
        temp->item = p->item;
        front = temp;
        while (p->next != NULL and p != rear)
        {
            p = p->next;
            Node* temp1 = new Node;
            temp1->item = p->item;
            temp->next = temp1;
            temp = temp->next;
        }
        temp->next = nullptr;
        rear = temp;
    }
    return *this;
}



bool Queue::isempty() const
{
    return items == 0;
}
bool Queue::isfull() const
{
    return items == qsize;
}
int Queue::queuecount()
{
    return items;
}

bool Queue::enqueue(const Item& item)
{
    if (isfull())
        return false;

    Node* add = new Node;
    add->item = item;
    add->next = nullptr;
    if (front == nullptr)
        front = add;
    else
        rear->next = add;
    rear = add;
    items++;
    return true;
}

bool Queue::dequeue(Item& item)
{
    if (isempty())
        return false;

    item = front->item;
    Node* temp = front;
    if (front == rear)
        front = rear = nullptr;
    else
        front = front->next;
    delete temp;
    items--;
    return true;
}
// corresponding to bank.cpp in book
#include<iostream>
#include<cstdlib>
#include<ctime>
#include"queue.h"

const int MINU_PER_HR = 60;

bool newcustomer(double x); // 判断是否有新的客户到来

int main()
{
    using std::cout;
    using std::cin;
    using std::endl;
    using std::ios_base;

    srand(time(0)); // 设置新的随机种子

    cout << "Bank of Automatic Teller Machine\n";
    cout << "Enter max size of queue: ";
    int qs;
    cin >> qs;
    Queue line1(qs); // line queue holds up to qs people, initialize to an empty queue
    Queue line2(qs);

    cout << "Enter the number of simulation hours: ";
    int hours;
    cin >> hours;
    // simulation will run 1 cycle per minute
    long cyclelim = hours * MINU_PER_HR;

    cout << "Enter the average number of customers per hour: ";
    double perhour;
    cin >> perhour;
    double minu_per_cust = MINU_PER_HR / perhour; // average time between arrivals

    long turnaways = 0; // turned away by full queue
    long customers = 0; // joined the queue
    long served = 0; // served during the simulation
    long sum_line = 0; // cumulative line length
    int wait_time1 = 0; // time=0 until autoteller is free
    int wait_time2 = 0; // time=0 until autoteller is free
    long line_wait = 0; // cumulative time in line


    // run simulation
    Item temp;
    for (int cycle = 0; cycle < cyclelim; cycle++)
    {
        // 每分钟开始判断是否有新的顾客到来
        if (newcustomer(minu_per_cust)) // 如果有新的顾客到来
        {
            if (line1.isfull() and line2.isfull())
            {
                turnaways++;
                cout << turnaways << "th customer turn away.\n";
            }

            else
            {
                customers++;
                temp.set(cycle);
                if (line1.queuecount() < line2.queuecount())
                    line1.enqueue(temp);
                else
                    line2.enqueue(temp);
                //cout << customers << "th customer enqueue\n";
            }
        }

        if (wait_time1 <= 0 and !line1.isempty())
        {
            line1.dequeue(temp);
            wait_time1 = temp.ptime();
            line_wait += cycle - temp.when();
            served++;
        }
        if (wait_time2 <= 0 and !line2.isempty())
        {
            line2.dequeue(temp);
            wait_time2 = temp.ptime();
            line_wait += cycle - temp.when();
            served++;
        }

        if (wait_time1 > 0)
        {
            wait_time1--;
            //cout << served << "th customer serving----------\n";
        }
        if (wait_time2 > 0)
        {
            wait_time2--;
            //cout << served << "th customer serving----------\n";
        }

        sum_line += line1.queuecount();
        sum_line += line2.queuecount();
    }

    // report results
    if (customers > 0)
    {
        cout << "Customer accepted: " << customers << endl;
        cout << "Customer served: " << served << endl;
        cout << "Turned aways: " << turnaways << endl;
        cout << "Average queue size: ";
        cout.precision(2);
        cout.setf(ios_base::fixed, ios_base::floatfield);
        cout << double(sum_line) / 2 / cyclelim << endl;
        cout << "Average wait time: " << double(line_wait) / served << "minutes\n";
    }
    else
    {
        cout << "No customers.\n";
    }

    return 0;
}

bool newcustomer(double x)
{
    // 能模拟每x分钟会有一个顾客到来
    return x * rand() / RAND_MAX < 1;
}

 

posted @ 2023-02-15 14:52  Triphan  阅读(72)  评论(0)    收藏  举报