C++PrimePlus学习——第十二章编程练习

12-1
Cow.h

#ifndef COW_H_
#define COW_H_
class Cow {
	char name[20];
	char* hobby;
	double weight;
public:
	Cow();
	Cow(const char* num, const char* ho, double wt);
	Cow(const Cow& c);
	~Cow();
	Cow& operator=(const Cow& c);
	void ShowCow() const;
};
#endif // !COW_H_

Cow.cpp

#include <iostream>
#include "Cow.h"
#include <cstring>
using std::cout;
using std::endl;

Cow::Cow()
{
	name[0] = '\0';
	hobby = new char[1];
	hobby[0] = '\0';
	weight = 0;
}
Cow::Cow(const char* nm, const char* ho, double wt)
{
	strcpy_s(name, nm);
	hobby = new char[std::strlen(ho) + 1];
	strcpy_s(hobby, std::strlen(ho) + 1, ho);
	weight = wt;
}
Cow::Cow(const Cow& c)
{
	strcpy_s(name, c.name);
	hobby = new char[std::strlen(c.hobby) + 1];
	strcpy_s(hobby, std::strlen(c.hobby) + 1, c.hobby);
	weight = c.weight;
}
Cow::~Cow()
{
	delete[] hobby;
}
Cow& Cow::operator=(const Cow& c)
{
	strcpy_s(name, c.name);
	hobby = new char[std::strlen(c.hobby) + 1];
	strcpy_s(hobby, std::strlen(c.hobby) + 1, c.hobby);
	weight = c.weight;
	return *this;
}
void Cow::ShowCow() const
{
	
	cout << "name: " << name << endl;
	cout << "hobby: " << hobby << endl;
	cout << "weigt: " << weight << endl;
}

main.cpp

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

int main()
{
    Cow a;
    a.ShowCow();
    Cow b("Bob", "Swiming", 60.0);
    b.ShowCow();
    a = b;
    a.ShowCow();
    return 0;
}

12-2
注意重载operator+时存在不同类型,一种是String+String,另一种是char*+String
string2.h

#ifndef STRING2_H_
#define STRING2_H_
#include <iostream>
using std::istream;
using std::ostream;
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& st, const String& st2);
	friend bool operator>(const String& st, const String& st2);
	friend bool operator==(const String& st, 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 c);
	friend String operator+(const char* s, const String& st);
	friend String operator+(const String& st1, const String& st2);
};
#endif // !STRING2_H_

string2.cpp
visual studio直接用strcpy会报错,故用strcpy_s

#include <iostream>
#include <cstring>
#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];
    strcpy_s(str, len + 1, 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];
    strcpy_s(str, len + 1, 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];
    strcpy_s(str, len + 1, st.str);
    return *this;
}

String& String::operator=(const char* s)
{
    delete[] str;
    len = std::strlen(s);
    str = new char[len + 1];
    strcpy_s(str, len + 1, 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;
}

//新增部分
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 count = 0;
	for (int i = 0; i < len; i++)
	{
		if (str[i] == c)
			count++;
	}
	return count;
}

String operator+(const char* st1, const String& st2)
{
    String st;
    st.len = strlen(st1) + st2.len;
    st = new char[st.len + 1];
    for (int i = 0; i < strlen(st1); i++)
    {
        st[i] = st1[i];
    }
    for (int i = strlen(st1); i < st.len; i++)
    {
        st[i] = st2[i - strlen(st1)];
    }
    st.str[st.len] = '\0';
    return st;
}

String operator+(const String& st1, const String& st2)
{
    String st;
    st.len = st1.len + st2.len;
	st = new char[st.len + 1];
    for (int i = 0; i < st1.len; i++)
    {
        st[i] = st1[i];
    }
    for (int i = st1.len; i < st.len; i++)
    {
        st[i] = st2[i - st1.len];
    }
    st.str[st.len] = '\0';
	return st;
}

main.cpp

#include <iostream>
#include "string2.h"
using namespace std;
int main()
{
	String s1(" and I an a C++ student.");
	String s2 = "Please entr 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' characrers n 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
除了修改头文件和源文件外,主函数中的top->show()改为cout << *top,测试重载是否成功
Stock20.h

#ifndef STOCK20_H_
#define STOCK20_H_
#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();
	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 // !STOCK20_H_

Stock20.cpp

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

Stock::Stock()
{
	char company[1];
	company[0] = '\0';
	shares = 0;
	share_val = 0.0;
	total_val = 0.0;
}

Stock::Stock(const char* co, long n, double pr)
{
	int len = std::strlen(co);
	company = new char[len + 1];
	strcpy_s(company, len + 1, co);
	if (n < 0)
	{
		std::cout << "Number of shares can't be ngative; "
			<< 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)
	{
		std::cout << "Number of shares purchased can't be negative. "
			<< "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& ch)
{
	using std::cout;
	using std::ios_base;
	ios_base::fmtflags orig =
		cout.setf(ios_base::fixed, ios_base::floatfield);
	std::streamsize prec = cout.precision(3);

	cout << "Company: " << ch.company
		<< " Shares: " << ch.shares << '\n';
	cout << " Share Price: $" << ch.share_val;

	cout.precision(2);
	cout << "  Total Worth: $" << ch.total_val << '\n';

	cout.setf(orig, ios_base::floatfield);
	cout.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.h"
using std::cout;
const int STKS = 4;
int main()
{
    using std::cout;
    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)
    };

    cout << "Stock holding:\n";
    int i;
    for (i = 0; i < STKS; i++)
        cout << stocks[i];

    const Stock* top = &stocks[0];
    for (i = 1; i < STKS; i++)
        top = &top->topval(stocks[i]);
    cout << "\nMost valuable holding:\n";
    cout << *top;
    return 0;
}

12-4
Stack.h

#ifndef STACK_H_
#define STACK_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& operator=(const Stack& st);
};
#endif // !STACK_H_

Stack.cpp

#include "Stack.h"

Stack::Stack(int n)
{
	size = n;
	pitems = new Item[n];
	top = 0;
}
Stack::Stack(const Stack& st)
{
	size = st.size;
	pitems = new Item[size];
	for (int i = 0; i < size; i++)
		pitems[i] = st.pitems[i];
	top = st.top;
}
Stack::~Stack()
{
	delete[] pitems;
	size = top = 0;
}
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;
	size = st.size;
	pitems = new Item[size];
	for (int i = 0; i < size; i++)
		pitems[i] = st.pitems[i];
	top = st.top;
	return *this;
}
main.cpp
#include <iostream>
#include <cctype>
#include "Stack.h"

int main()
{
	using namespace std;
	Stack pst;
	Item j;
	cout << pst.isempty() << endl;
	cout << pst.isfull() << endl;
	for (int i = 0; i < 10; i++)
	{
		pst.push(i);
	}
	cout << pst.isfull() << endl;
	Stack tst;
	cout << tst.isempty() << endl;
	tst = pst;
	cout << tst.isempty() << endl;
	for (int i = 0; i < 10; i++)
	{
		tst.pop(j);
		cout << j << " popped ";
	}
	return 0;
}

12-5
指针初始化为nullptr,和书上一样,尝试之后,发现(10, 100, 18)时在1min左右,(10,100,19)时一般大于1min,书上少了个<< "average queue size: "
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; 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_H_

queue.cpp

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

Queue::Queue(int qs) : qsize(qs)
{
	front = rear = nullptr;
	items = 0;
}

Queue::~Queue()
{
	Node* temp;
	while (front != nullptr)
	{
		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 = nullptr;
	items++;
	if (front == nullptr)
		front = add;
	else
		rear->next = add;
	rear = add;
	return true;
}

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

void Customer::set(long when)
{
	processtime = std::rand() % 3 + 1;
	arrive = when;
}

main.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;
	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;
	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.precision(2);
		cout.setf(ios_base::fixed, ios_base::floatfield);
		cout << "average queue size: "
			<< (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
加一个wait_time进行比较就行了,有个地方1和2写反了,研究了好久,看别人代码比较了半天才发现,以后一定要细心,(10,100,18)只需要0.34min了,(10,100,51)在1min左右,(10,100,52)超过1min
main.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;
	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;
	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
			{
				temp.set(cycle);
				line1.enqueue(temp);
				customers++;
			}
		}
		if (wait_time1 <= 0 && !line1.isempty())
		{
			line1.dequeue(temp);
			wait_time1 = temp.ptime();
			line_wait += cycle - temp.when();
			served++;
		}
		if (wait_time2 <= 0 && !line2.isempty())
		{
			line2.dequeue(temp);
			wait_time2 = temp.ptime();
			line_wait += cycle - temp.when();
			served++;
		}
		if (wait_time1 > 0)
			wait_time1--;
		if (wait_time2 > 0)
			wait_time2--;
		sum_line += line1.queuecount() + line2.queuecount();
	}
	if (customers > 0)
	{
		cout << "customers accepted: " << customers << endl;
		cout << "  customers served: " << served << endl;
		cout << "         turnaways: " << turnaways << endl;
		cout.precision(2);
		cout.setf(ios_base::fixed, ios_base::floatfield);
		cout << "average queue size: "
			<< (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);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值