C++Primerplus 编程练习 第十二章
第十二章
第一题
//cow.h
#pragma once
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;
};
//cow.cpp
#include "cow.h"#include <cstring>
#include <iostream>
Cow::Cow()
{name[0] = '\0';hobby = new char[1];hobby[0] = '\0';weight = 0.0;
}
Cow::Cow(const char *nm, const char *ho, double wt)
{strcpy(name, nm);hobby = new char[strlen(ho) + 1];strcpy(hobby, ho);weight = wt;
}
Cow::Cow(const Cow &c)
{strcpy(name, c.name); hobby = new char[strlen(c.hobby) + 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;strcpy(name, c.name);hobby = new char[strlen(c.hobby) + 1];strcpy(hobby, c.hobby);weight = c.weight;return *this;
}
void Cow::ShowCow() const
{using namespace std;cout << "cow's name is " << name << endl<< "hobby is " << hobby << endl<< "weight is " << weight << endl;
}
//main.cpp
#include <iostream>#include "cow.h"
int main()
{using namespace std;Cow a;Cow b("hick", "eating grass", 87);Cow c(b);Cow e;e = b;cout << "default a" << endl;a.ShowCow();cout << "b is" << endl;b.ShowCow();cout << "c is" << endl;c.ShowCow();cout << "e is" << endl; e.ShowCow();return 0;
}
第二题
我移除了num_strings
和Howmany()
因为在这个示例里面用不到
//string2.h
#pragma once
#include <iostream>
using std::istream;
using std::ostream;class String
{
private:char *str;int len;static const int CINLIM = 80;public:String(const char *s);String();String(const String &s);~String();int length() const { return len; }void Stringlow();void Stringup();int has(char c);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);
};
//string2.cpp
#include "string2.h"#include <cctype>
#include <cstring>
#include <iostream>
using std::cin;
using std::cout;String::String(const char *s)
{len = strlen(s);str = new char[len + 1];strcpy(str, s);
}
String::String()
{len = 0;str = new char[1];str[0] = '\0';
}
String::String(const String &s)
{len = s.len;str = new char[len + 1];strcpy(str, s.str);
}
String::~String() { delete[] str; }
void String::Stringlow()
{for (int i = 0; i < len; i++) str[i] = tolower(str[i]);
}
void String::Stringup()
{for (int i = 0; i < len; i++) str[i] = toupper(str[i]);
}
int String::has(char c)
{int n = 0;for (int i = 0; i < len; i++) {if (str[i] == c) n++;}return n;
}
String &String::operator=(const String &st)
{if (this == &st) return *this;delete[] str;len = st.len;str = new char[len + 1]; strcpy(str, st.str);return *this;
}
String &String::operator=(const char *s)
{delete[] str;len = strlen(s);str = new char[len + 1];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 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;
}
String operator+(const String &st1, const String &st2)
{String res;res.len = st1.len + st2.len;res.str = new char[res.len + 1];strcpy(res.str, st1.str);strcpy(res.str + st1.len, st2.str);return res;
}
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;
}
//main.cpp
#include <iostream>#include "string2.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.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;elsecout << "Try again!\n";}cout << "Bye\n";return 0;return 0;
}
第三题
//stock20.h
#pragma once
#include <iostream>
using std::ostream;
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(const Stock &s);~Stock();void buy(long num, double price);void sell(long num, double price);void update(double price);const Stock &topval(const Stock &s) const;Stock &operator=(const Stock &s);friend ostream &operator<<(ostream &os, const Stock s);
};
//stock20.cpp
#include "stock20.h"#include <cstring>
#include <iostream>Stock::Stock() : shares(0), share_val(0.0), total_val(0.0)
{company = new char[]{"no name"};
}
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;} elseshares = n;share_val = pr;set_tot();
}
Stock::Stock(const Stock &s)
{shares = s.shares;share_val = s.share_val;total_val = s.total_val;company = new char[strlen(s.company) + 1];strcpy(company, s.company);
}
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 ia 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();
}
const Stock &Stock::topval(const Stock &s) const
{if (s.total_val > total_val)return s;elsereturn *this;
}
Stock &Stock::operator=(const Stock &s)
{if (this == &s) return *this;shares = s.shares;share_val = s.share_val;total_val = s.total_val;delete[] company;company = new char[strlen(s.company) + 1];strcpy(company, s.company);return *this;
}
ostream &operator<<(ostream &os, const Stock s)
{using std::cout;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 << '\n';os << " Share Price: $" << s.share_val;cout.precision(2);os << " Total worth: $" << s.total_val << '\n';os.setf(orig, ios_base::floatfield);os.precision(prec);return os;
}
第四题
#pragma once
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);
};
#include "stack.h"#include <iostream>Stack::Stack(int n)
{if (n > MAX) {std::cout << "超出最大上限,现初始化为 " << MAX << '\n';size = MAX;} else if (n < 0) {std::cout << "栈的大小不能为负, 现初始化为 " << MAX << '\n'; } else {size = n;}top = 0;pitems = new Item[size];
}
Stack::Stack(const Stack &st)
{size = st.size;top = st.top;pitems = new Item[size];for (int i = 0; i < size; i++) {pitems[i] = st.pitems[i];}
}
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 (isfull()) return false;pitems[top++] = item;return true;
}
bool Stack::pop(Item &item)
{if (isempty()) return false;item = pitems[--top];return true;
}
Stack &Stack::operator=(const Stack &st)
{if (this == &st) return *this;size = st.size;top = st.top;delete[] pitems;pitems = new Item[size];for (int i = 0; i < size; i++) {pitems[i] = st.pitems[i];}return *this;
}
//main.cpp
#include <iostream>#include "stack.h"
int main()
{using namespace std;Stack s1;cout << "s1 isempty " << s1.isempty() << endl;s1.push(12);s1.push(1);s1.push(2);s1.push(10);s1.push(1008); Stack s2(100);s2 = s1;Item a;s2.pop(a);cout << a << endl;Stack s3(s2);return 0;
}
第五题
//queue.h#pragma onceclass 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);};
//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;elserear->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;
}
//bank.cpp
#include <cstdlib>
#include <ctime>
#include <iostream>#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;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 customers 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;int wait_time = 0;long line_wait = 0;// simulationfor (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";} elsecout << "No customers!\n";cout << "Done!\n";return 0;
}bool newcustomer(double x) { return std::rand() * x / RAND_MAX < 1; }
大概每小时17人平均等候时间为1分钟
第六题
//bank.cpp
#include <cstdlib>
#include <ctime>
#include <iostream>#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;Queue line1(qs);Queue line2(qs);cout << "Enter the number of simulation hours: ";int hours;cin >> hours;long cyclelimit = MIN_PER_HR * hours;cout << "Enter the average number of customers 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;int wait_time1 = 0;int wait_time2 = 0;long line_wait = 0;// simulationfor (int cycle = 0; cycle < cyclelimit; cycle++) {if (newcustomer(min_per_cust)) {if (line1.queuecount() < line2.queuecount()) {customers++;temp.set(cycle);line1.enqueue(temp);} else if (!line2.isfull()) {customers++;temp.set(cycle);line2.enqueue(temp);} else {turnaways++;}}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();}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";} elsecout << "No customers!\n";cout << "Done!\n";return 0;
}bool newcustomer(double x) { return std::rand() * x / RAND_MAX < 1; }