C.Primer.Plus(第六版)第12章 编程练习

来源:互联网 发布:python 垃圾回收 阈值 编辑:程序博客网 时间:2024/05/16 06:58

//12.1

// cow.h#ifndef COW__H__#define COW__H__class Cow{private:    static const int N = 20;    char name[N];    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 <iostream>#include "cow.h"Cow::Cow(){    strcpy(name,"NULL");    hobby = new char[1];    hobby[0] = '\0';    weight = 0.0;}Cow::Cow(const char* nm,const char* ho,double wt){    int len = strlen(nm);    strncpy(name,nm,len<N-1?len:N-1);    if(len<N-1)        name[len]='\0';    else        name[N-1]='\0';    int size = strlen(ho);    hobby = new char[size+1];    strcpy(hobby,ho);    weight = wt;}Cow::Cow(const Cow & c){    strcpy(name,c.name);    int len = strlen(c.hobby);    hobby = new char[len+1];    strcpy(hobby,c.hobby);    weight = c.weight;}Cow::~Cow(){    delete [] hobby;//对应构造函数}Cow & Cow::operator=(const Cow & c){    if(this == &c)        return *this;    delete [] hobby;    int len = strlen(c.hobby);    hobby = new char[len+1];    strcpy(hobby,c.hobby);    strcpy(name,c.name);    weight = c.weight;    return *this;}void Cow::ShowCow() const{    std::cout<<"the cow name is "<<name<<" , the hobby is "        <<hobby<<" , and the weight is "<<weight<<std::endl;}
//main.cpp#include <iostream>#include "cow.h"int main(){    using namespace std;    Cow cow_one;    cow_one.ShowCow();    Cow cow_two("mmdnxh","reading",20);    cow_two.ShowCow();    Cow cow_three(cow_two);    cow_three.ShowCow();    cow_one = cow_three;    cow_one.ShowCow();    return 0;}

//12.2

//string2.h  fixed and augmented string class definition#ifndef STRING1__H__#define STRING1__H__#include <iostream>using std::istream;using std::ostream;class String{private:    char* str; //pointer to string    int len;   //length of string    static int num_strings;  //number of objects    static const int CINLIM = 80; //cin input limitpublic:    //constructors and other methods    String(const char* s);    String();    String(const String &);    ~String();    int length() const {return len;}    // overloaded operator methods    String & operator=(const String &);    String & operator=(const char*);    char & operator[](int i);    const char & operator[](int i) const;    String & operator+(const char*);    String  operator+(const String & s);    //overloads operator friends    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 ostream & operator<<(ostream & os,const String & st1);    friend istream & operator>>(istream & is,String & st1);    friend String operator+(const char* st,const String & s2);    static int HowMany();    void Stringlow();    void Stringupper();    int Charcount(const char);};#endif
//string1.cpp --String class methods#include <cstring>#include "string1.h"using std::cout;using std::cin;int String::num_strings = 0;int String::HowMany(){    return num_strings;}String::String(const char* s){    len = strlen(s);    str = new char[len+1];    std::strcpy(str,s);    num_strings++;}String::String(){    str = new char[1];    //str = 0;    //str = nullptr;//c++11    str[0] = '\0';    num_strings++;}String::String(const String & st)//传入的引用对象,并不会产生临时对象//todo{    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)//todo{    if(this == &st)        return *this;    delete [] str;    len = st.len;    str = new char[len+1];    std::strcpy(str,st.str);    //num_strings++;    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];}String & String::operator+(const char* s){    char* temp = new char[len+1];    strcpy(temp,str);    delete [] str;    int s_len = strlen(s);    str = new char[s_len+1+len+1];    strcpy(str,temp);    strcat(str,s);    len = strlen(temp)+1+s_len;    delete [] temp;    return *this;}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 (strcmp(st1.str,st2.str) == 0);}ostream & operator<<(ostream & os, const String & st1){    os<<st1.str;    return os;}istream & operator>>(istream & is,String & st1){    char temp[String::CINLIM];    is.get(temp,String::CINLIM);    if(is)        st1 = temp;    is.sync();    is.clear();    //while(is && is.get() != '\n')    //  continue;    return is;}String operator+(const char* st,const String & s2){    String s;    delete [] s.str;    s.str = new char[strlen(st)+1+s2.len+1];    strcpy(s.str,st);    strcat(s.str,s2.str);    s.len = strlen(st)+1+s2.len;    return s;}String String::operator+(const String & s){    //String temp((*this).str+s);    String temp;    delete [] temp.str;    temp.str = new char[strlen(str)+1+strlen(s.str)+1];    strcpy(temp.str,str);    strcat(temp.str,s.str);    temp.len = strlen(str)+1+s.len;    return temp;}void String::Stringlow(){    //while(*str !='\0')     //{                     //先取值再自增,即指向下一地址    //  *str = tolower(*str);//参数为大写字符,则返回小写,否则返回该参数    //  str++;              //为什么不把str++写到判断中,即(while(*str++ != '\0'))因为while判断是一个顺序点,在判断完副作用后再执行后一条语句.    //}                     //int x=8;while(x++ <10) cout<<x<<endl; 将会输出9,10。即先while判断为一个顺序点,在判断完副作用后再执行后一条语句,即先自增在输出。    for(int i = 0;i<len;i++)    {        if(isupper(str[i]))            str[i] = tolower(str[i]);    }}void String::Stringupper() {    //while(*str != '\0')//为什么不能将更改后的数据放回去,    //{    //  if(islower(*str))    //      *str = toupper(*str);    //      //cout<<*str;//这里输出也正常啊。。。留个问题,以后再来。    //  str++;    //}    for(int i = 0;i<len;i++)    {        if(islower(str[i]))            str[i] = toupper(str[i]);    }}int String::Charcount(const char ch){    int count = 0;    //while(*str != '\0' && *str == c)    //{    //  count++;    //  str++;    //}    for(int i =0;i<len;i++)    {        if(str[i] == ch)            count++;    }    return count;}
//pe12_2.cpp#include <iostream>using namespace std;#include "string1.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;    cout<<s2<<"1.\n";    s2.Stringupper();    cout<<s2<<"dff.\n";    cout<<"The string\n"<<s2<<"\ncontains "<<s2.Charcount('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;}

//12.3

//stock20_new.h#ifndef STOCK20_NEW__H__#define STOCK20_NEW__H__#include <iostream>class Stock{private:    char* str;    int shares;    double share_val;    double total_val;    void set_tot() {total_val = shares * share_val;}public:    Stock();    Stock(const char* s ,long n = 0,double pr = 0.0);    ~Stock();    void buy(long num, double price);    void sell(long num,double price);    void update (double price);    const Stock & topval(const Stock & s) const;    friend std::ostream & operator<<(std::ostream & os,const Stock & s);};#endif
//stock20_new.cpp#include <iostream>#include "stock20_new.h"Stock::Stock(){    str = new char[1];    str[0] = '\0';    shares = share_val = total_val = 0;}Stock::Stock(const char* s,long n,double pr){    str = new char[strlen(s)+1];    strcpy(str,s);    if(n<0)    {        std::cout<<"Number of shares can't be negative,"        <<str<<" shares set tp 0.\n";    shares = 0;    }    else        shares = n;    share_val =pr;    set_tot();}Stock::~Stock(){    delete [] str;}void Stock::buy(long num , double price){    if(num<0)    {        std::cout<<"Number of shares purchasef can't be negative,"        <<str<<"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)    {        std::cout<<"Number of shares sold can't be negative,"        <<str<<"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 & 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.str        <<" Share:"<<s.shares<<'\n';    os<<" Share Price: $"<<s.share_val<<os.precision(2);    os<<" Total Worht: $"<<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 > total_val)        return s;    else         return *this;}
//main.cpp#include <iostream>#include "stock20_new.h"const int STKS = 4;int main(){    Stock stocks[4] = {        Stock("NanoSma",12,20.0),        Stock("Boffo Objects",200,2.0),        Stock("Monolithic Obelisks",130,2.25),        Stock("Fleep Enterpricses",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 valueable holding :\n";    std::cout<<*top;    return 0;}

//12.4

//stack.h#ifndef STACK_NEW__H__#define STACK_NEW__H__typedef unsigned long Item;//表示栈中元素的类型class Stack{private:    enum{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 & Stack::operator=(const Stack & st);    void Stackshow();};#endif
#include <iostream>#include "stack.h"Stack::Stack(int n){    pitems = new Item[n];    top = 0;    size = n;}Stack::Stack(const Stack & st){    size = st.size;    top = st.top;    pitems = new Item[st.size];    for(int i =0;i<st.top;i++)    {        pitems[i] = st.pitems[i];    }}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;        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;    delete [] pitems;    pitems = new Item[st.size];    for(int i =0;i<st.top;i++)    {        pitems[i] = st.pitems[i];    }    size = st.size;    top = st.top;    return *this;}void Stack::Stackshow(){    for(int i =0;i<top;i++)        std::cout<<pitems[i]<<" ";    std::cout<<std::endl;    std::cout<<"size: "<<size<<" ,top: "<<top<<std::endl;}
//stack_new.cpp#include <iostream>#include <cctype>#include "stack.h"int main(){    using namespace std;    Stack st(20);    char ch;    unsigned long po;    cout<<"Please enter A to add a purchase order,\n"        <<"P to process a PO,ir Q to quit.\n";    while(cin>>ch && toupper(ch)!='Q')    {        while(cin.get() != '\n')            continue;        if(!isalpha(ch))        {            cout<<'\a';            continue;        }        switch(ch)        {        case 'a':        case 'A':            cout<<"Enter a PO number to add: ";            cin>>po;            if(st.isfull())                cout<<"stack already full\n";            else                 st.push(po);            break;        case 'p':        case 'P':            if(st.isempty())                cout<<"stack already empty\n";            else            {                st.pop(po);                cout<<"PO #"<<po<<" popped\n";            }            break;        }        cout<<"Please enter A to add a purchase order,\n"            <<"P to process a PO,or Q to quit.\n";    }    cout<<"Bye!\n";    Stack new_st(st);    new_st.Stackshow();    Stack te_st = new_st;    te_st.Stackshow();    return 0;}

//12.5

//queue.h#ifndef QUEUE__H__#define QUEUE__H__//This quene will contain Customer itemsclass Customer{private:    long arrive;// arrival time for customer    int processtime;//processing time for customer 交易时间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:    enum{Q_SIZE = 10};    struct Node    {        Item item;        struct Node* next;    };    //private class members    Node* front; //pointer to front of Quene    Node* rear;  //pointer to rear of Quene    int items;   //current number of items in Queue    const int qsize;  // maximum number of items in Queue    Queue(const Queue & q) : qsize(0){}//member initialization list 成员初始化列表    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
//quene.cpp#include <cstdlib>#include "queue.h"//Queue methodsQueue::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;}//Add item to queuebool 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(isempty())        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;}
//bank.cpp  using the Queue interface#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;    //setting things up    std::srand(std::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<<"Enter the number of simulation hours: ";    int hours;    cin>>hours;//测试时间    // simulation will run 1 cycle per minute    long cyclelimit = MIN_PER_HR * hours;//循环次数    cout<<"Enter the average number of customer per hour: ";    double perhour;    cin>>perhour;//一小时多少客户    double min_per_cust;    min_per_cust = MIN_PER_HR / perhour;//每分钟多少客户    Item temp;// new customer data     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 lentgth 累计长度    int wait_time = 0;//time until autoteller is free    long line_wait = 0;//cumulative time in line    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++;        }        //  先将数据保存,释放结点,再判断wait_time,可以理解为如果排队到第一个位置,则进入一个特殊的房间而不在队列中,但操作时间是从这时算起的(对后面排队的而言)。        //上面的逻辑大致是这样的,第一次,首先,如果前面已经有客户入队了,那么这时if判断是都满足(wait_time时间初始化为0且队列也不为空),进入if,        //这个时候的出队操作的思路是这样的,首先将头结点(p1)的客户数据取出来放在temp中,然后释放头结点(p1),(注意,temp对象仍存在),front指针指向下一个结点,即新的头结点(p2)。        //但wait_time为被释放掉头结点(p1)的等候时间(保存在temp中)。        //执行循环当wait_time再次为零时(默认有客户),进入if判断,再次出队,front指针指向头结点(p3),这时wait_time为头结点(p2)的等候时间....以此循环。        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";    cout<<"Done!\n";    return 0;}bool newcustomer(double x){    return (std::rand() * x / RAND_MAX <1);}  

//12.6

//queue.h#ifndef QUEUE__H__#define QUEUE__H__//This quene will contain Customer itemsclass Customer{private:    long arrive;// arrival time for customer    int processtime;//processing time for customer 交易时间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:    enum{Q_SIZE = 10};    struct Node    {        Item item;        struct Node* next;    };    //private class members    Node* front; //pointer to front of Quene    Node* rear;  //pointer to rear of Quene    int items;   //current number of items in Queue    const int qsize;  // maximum number of items in Queue    Queue(const Queue & q) : qsize(0){}//member initialization list 成员初始化列表    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);    int Showitems();};#endif
//quene.cpp#include <cstdlib>#include "queue.h"//Queue methodsQueue::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;}//Add item to queuebool 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(isempty())        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;}int Queue::Showitems(){    return items;}
//bank.cpp  using the Queue interface#include <iostream>#include <cstdlib>#include <ctime>#include "queue.h"const int MIN_PER_HR = 60;bool newcustomer(double x);int main(){    while(1)    {        using std::cin;        using std::cout;        using std::endl;        using std::ios_base;        //setting things up        std::srand(std::time(0));        cout<<"Case Study:Bank of Heather Automatic Teller\n";        cout<<"Enter maximum size of queue:";        int qs;        cin>>qs;        Queue line1(qs),line2(qs);//队列长度        cout<<"Enter the number of simulation hours: ";        int hours;        cin>>hours;//测试时间        // simulation will run 1 cycle per minute        long cyclelimit = MIN_PER_HR * hours;//循环次数        cout<<"Enter the average number of customer per hour: ";        double perhour;        cin>>perhour;//一小时多少客户        double min_per_cust;        min_per_cust = MIN_PER_HR / perhour;//每分钟多少客户        Item temp1,temp2;// new customer data         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 lentgth 累计长度        int wait_time1 = 0 ,wait_time2 = 0;//time until autoteller is free        long line_wait = 0;//cumulative time in line        for(int cycle = 0;cycle<cyclelimit;cycle++)        {            //Queue choice = line1.items>line2.items?line2:line1;            if(newcustomer(min_per_cust))//有客户访问            {                if(line2.Showitems()>line1.Showitems())                {                    if(line1.isfull())//队列是否满员                        turnaways++;                    else                    {                        customers++;                        temp1.set(cycle);//将进队时的时间记录下来,用于记录在队列中的时间,以及操作时间                        line1.enqueue(temp1);//入队                    }                }                else                {                    if(line2.isfull())//队列是否满员                        turnaways++;                    else                    {                        customers++;                        temp2.set(cycle);//将进队时的时间记录下来,用于记录在队列中的时间,以及操作时间                        line2.enqueue(temp2);//入队                    }                }            }            if(wait_time1<=0 && !line1.isempty())//如果客户操作完成            {                line1.dequeue(temp1);//出队并将指针指向新的头结点                wait_time1 = temp1.ptime();//得到被释放头结点的操作时间                line_wait += cycle - temp1.when();//从排队到开始操作的时间                served++;            }            if(wait_time1>0)                wait_time1--;            sum_line += line1.queuecount();            if(wait_time2<=0 && !line2.isempty())//如果客户操作完成            {                line2.dequeue(temp2);//出队并将指针指向新的头结点                wait_time2 = temp2.ptime();//得到被释放头结点的操作时间                line_wait += cycle - temp2.when();//从排队到开始操作的时间                served++;            }            if(wait_time2>0)                wait_time2--;            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";        cout<<"Done!\n";    }    return 0;//通过测试发现50个人一个小时时满足平均等候时间为1分钟}bool newcustomer(double x){    return (std::rand() * x / RAND_MAX <1);}