类和动态内存分配的课后习题(C++ prime plus)

第一题

1. 对于下面的类声明:

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; // display all new data

};

给这个类提供实现,并编写一个使用所有成员函数的小程序。
Cow.h

#ifndef COW_H_
#define COW_H_

class Cow
{
    private:
        char name[20];
        char * hobby;
        double weght;
    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 <cstring>
#include "Cow.h"
using namespace std;


Cow::Cow()
{
    strcpy(name,"whp");
    hobby=new char [4];
    strcpy(hobby,"math");
    weght=0.0;    
}


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

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

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


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


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

UserCow.cpp

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

int main()
{
    Cow mycow;
    mycow.ShowCow();
    Cow mycow1("wer","china",20);
    mycow1.ShowCow();
    Cow mycow2;
    mycow2=mycow;
    mycow2.ShowCow();
    cout<<"结束"<<endl;
    return 0;
    
}

 第二题

通过完成下面的工作来改进String类声明(即将String1.h升级为String2.h)。

a. 对+运算符进行重载,使之可将两个字符串合并成1个。

b. 提供一个Stringlow()成员函数,将字符串中所有的字母字符转换为小写(别忘了cctype系列字符函数)。

c. 提供String()成员函数,将字符串中所有字母字符转换成大写。

d. 提供一个这样的成员函数,它接受一个char参数,返回该字符在字符串中出现的次数
string.h

#ifndef STRING1_H_
#define STRING1_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; }
    void string_change_low();
    void string_change_up();
    int has(char c);
    String & operator=(const String &);
    String & operator=(const char *);
    String operator+(const String & st)const;
    String operator+(const char * str1)const;
    char & operator[](int i);
    const char & operator[](int i) const;

    friend bool operator<(const String &st, const String &st2);
    friend bool operator>(const String &st1, const String &st2);
    friend bool operator==(const String &st, const String &st2);
    friend String operator+(const char * str1,const String & st);
    friend ostream & operator<<(ostream & os, const String & st);
    friend istream & operator>>(istream & is, String & st);

    static int HowMany();
};
#endif

string.cpp

#include <cstring>              
#include "string1.h"        
using std::cin;
using std::cout;
#include <cstdlib>


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 = 4;
    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; 
}


void String::string_change_low()
{
    for(int i=0;i<this->len+1;i++)
    {
        this->str[i]=towlower(this->str[i]);
    }
}

void String::string_change_up()
{
    for(int i=0;i<this->len+1;i++)
    {
        this->str[i]=toupper(this->str[i]);
    }
}
 int String::has(char c)
 {
    int count=0;
    for(int i=0;i<this->len+1;i++)
    {
        if(this->str[i]==c)
        {
            count++;
        }
    }
    return count;
 }


String String::operator+(const String & st)const
{
    int new_len=0;
    new_len=len+st.len;
    char * temp=new char [new_len+1];
    strcpy(temp,str);
    strcpy(temp+len,st.str);
    temp[new_len]='\0';
    return String(temp);

}


String String::operator+(const char * str1)const
{
    int new_len=0;
    new_len=len+strlen(str);
    char *temp=new char [new_len+1];
    strcpy(temp,str);
    strcpy(temp,str1);
    return String(temp);

}

String operator+(const char * str1,const String & st)
{
    return String(str1)+st;
}
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;
}

UserString.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;
    s2.string_change_up(); 
    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.string_change_low(); 
        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;
}

第三题

新编写程序清单10.7和程序清单10.8描述的Stock类,使之使用动态内存分配的内存,而不是string类对象来存储股票名称。另外,使用重载的operator<<()定义代替show()成员函数。再使用程序清单10.9测试新的定义程序。

Stock20.h

 

#ifndef STOCK20_H_
#define STOCK20_H_
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
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 * strs, 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);
    const Stock & topval(const Stock & s) const;
};

#endif

 

Stcok20.cpp

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


Stock::Stock() 
{
    company=new char [strlen("whp")+1];
    strcpy(company,"whp");
    shares = 0;
    share_val = 0.0;
    total_val = 0.0;
}

Stock::Stock(const char * strs, long n, double pr)
{
    int len=strlen(strs);
    company=new char [len+1];
    strcpy(company,strs);

    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() 
{
}


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();
}

ostream & operator<<(ostream & os,const Stock & st)
{

    using std::ios_base;
    
    ios_base::fmtflags orig =
        os.setf(ios_base::fixed, ios_base::floatfield);
    std::streamsize prec = os.precision(3);

    os << "Company: " <<st.company
        << " Shares: " <<st.shares << '\n';
    os << " Share Price: $" <<st.share_val;
    
    os.precision(2);
    os << " Total Worth: $" <<st.total_val <<'\n';
    return os;
}

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

UserStcok.cpp

#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)
        };

    std::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]);

    std::cout << "\nMost valuable holding:\n";
    cout<<*top;
     return 0;
}

 第四题

Stack.h

 

#ifndef STOCK_H_
#define STOCK_H_
using namespace std;
#include <iostream>
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 & operator=(const Stack & st);
    friend ostream & operator<<(ostream & os,const Stack & st);
};

#endif

 

Stack.cpp

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


Stack::Stack(int n=MAX)
{
    pitems=new Item[n];//分配空间
    for(int i=0;i<n;i++)//初始化数组
    {
        pitems[i]=0;
    }
    top=0;
    size=n;
}


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

Stack::~Stack()
{
    delete [] pitems;//释放内存
}


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

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

bool Stack::push(const Item & item)
{
    if(top<MAX)
    {
        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;
    top=st.top;
    size=st.size;
    pitems=new Item[st.size];
    for(int i=0;i<st.size;i++)
    {
        pitems[i]=st.pitems[i];
    }
    return *this;
    
}

ostream & operator<<(ostream & os,const Stack & st)
{
    for(int i=0;i<st.top;i++)
    {
        os<<st.pitems[i]<<endl;
    }
    return os;
}

UserStack.cpp

#include <iostream>
#include <cctype> 
#include "Stack.h"
int main()
{
    using namespace std;
    Stack st; 
    char ch;
    unsigned long po;
    cout << "Please enter A to add a purchase order,\n"
        << "P to process a PO, or 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";
    }
    Stack st2;
    st2=st;
    cout<<"st2"<<st2<<endl;
    cout << "Bye\n";
    return 0;
}

 第五题

Heather银行进行的研究表明,ATM客户不希望排队时间不超过1分钟。使用程序清单12.10中的模拟,找出要使平均等候时间为1分钟,每小时到达的客户数应为多少(试验时间不短于100小时)?

Queue.h

 

#ifndef STACK_H_
#define STACK_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;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

 

customer.cpp

 

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


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;
    rear->next=add;
    rear=add;
    return true;

}


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

 

bank.cpp

#include <iostream>
#include "Queue.h"
#include <cstdlib>
#include <ctime>

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:Band 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;
    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;
    long turnaways=0;
    long customers=0;
    long served=0;
    long sum_line=0;
    long wait_time=0;
    long line_wait=0;
    double avetime=0;

    while(perhour++&&avetime<=1)
    {
        while(!line.isempty())
        {
            line.dequeue(temp);
        }



    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();
    }

    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 inutes.\n"<<endl;
    cout<<"Done";
    return 0;
}


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

 

posted @ 2022-08-18 16:07  术术子  阅读(49)  评论(0编辑  收藏  举报