1. 程式人生 > >C++primer plus第六版課後程式設計練習答案12.5與12.6

C++primer plus第六版課後程式設計練習答案12.5與12.6

bank是第五題的實現,bank1是第六題的實現
#ifndef QUEUE_H_
#define QUEUE_H_

class Customer
{
private:
	int arrive;
	int processtime;
public:
	Customer(){arrive=processtime=0;}

	void set(int when);
	int when()const{return arrive;}
	int ptime()const{return processtime;}
	bool operator!=(const Customer &c)const;
	bool operator==(const Customer &c)const;

};

typedef Customer Item;

class Queue
{
private:
	struct Node{
		Item item;
		Node *next;
	};
	enum{Q_SIZE=10};

	Node *front;
	Node *rear;
	int items;
	const int qsize;
	int first_start_time;


	Queue(const Queue &q):qsize(0){}//
	Queue &operator=(const Queue &q){return *this;}//使類不能被複制

public:
	Queue(int qs=Q_SIZE);
//	Queue(Item &i);
	~Queue();
	void clearline();
	bool isempty();
	bool isfull();
	bool insertqueue(const Item &i);
	bool deletequeue(Item &i);
	int queuecount()const;
	int CusNumbefore(const Item &i)const;
	void set_first_start_time(const int t);
	int wait_time_min(const Item &i,const int t);//只有類成員函式後可加const,代表成員函式不能修改類的資料成員

};

#endif
#include<iostream>
#include "queue.h"
#include<cstdlib>//for rand()

using namespace std;

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

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


void Queue::clearline()
{
		Node *temp;
	while(front!=NULL)
	{
		temp=front;
		front=front->next;
		delete temp;
	}
	front=rear=0;
	items=0;
	first_start_time=0;
}

bool Queue::isempty()
{
	return items==0;
}

bool Queue::isfull()
{
	return items==qsize;
}

int Queue::queuecount()const
{
	return items;
}

bool Queue::insertqueue(const Item &i)
{
	if(isfull())
		return false;
	Node *add=new Node;
	add->item=i;
	add->next=NULL;
	items++;
	if(front==NULL)
		front=add;
	else 
		rear->next=add;
	rear=add;
	return true;	
}

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

int Queue::CusNumbefore(const Item &i)const
{
	Node *temp=front;
	int n=1;

	cout<<temp->item.when()<<endl<<temp->item.ptime()<<endl;//顯示客戶的加入時間和處理時間
	while(i!=temp->item)
	{
		if(temp==NULL)
			return -1;
		temp=temp->next;
		n++;
	}
	return n;

}

void Queue::set_first_start_time(const int t)
{
	first_start_time=t;
}


int Queue::wait_time_min(const Item &i,const int t)
{
	if(CusNumbefore(i)==-1)
	{
		cout<<"顧客i不在隊列當中"<<endl;
		return 0;
	}
	else
	{
		Node *temp=front;
		int wait_time=0;
			while(temp->item!=i)
			{
				temp=temp->next;
				wait_time+=temp->item.ptime();
			}
			return wait_time;

	}
}


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

bool Customer::operator!=(const Customer &c)const
{
	if((arrive==c.arrive)&&(processtime==c.processtime))
		return false;
	return true;
}

bool Customer::operator==(const Customer &c)const
{
	if((arrive==c.arrive)&&(processtime==c.processtime))
		return true;
	return false;
}
<pre name="code" class="cpp">#include<iostream>
#include<cstdlib>
#include<ctime>
#include "queue.h"

using namespace std;

const int MIN_PER_HR=60;

bool newcustomer(double x);

void bank();

void bank1();

int main()
{
	
	bank1();

	return 0;
}

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

void bank()
{
	
	srand(time(0));
	cout<<"Case Study:Bank of Heather Automatic Teller\n";
//	cout<<"Enter maximum size of queue:";
	int qs;
//	cin>>qs;
	qs=10;
	Queue line(qs);//輸入佇列最大長度

//	cout<<"Enter the number of simulation hours:";

	int hours;
//	cin>>hours;
	hours=100;
	long cyclelimit=MIN_PER_HR*hours;//輸入程式執行時間

//	cout<<"Enter the average number of customers per hour:";
	double perhour;
//	cin>>perhour;//輸入每小時到達的客戶數
	double min_per_cust;

	Item temp;
	long turnaways=0;
	long customers=0;
	long served=0;
	long sum_line=0;
	int  wait_time=0;
	long line_wait=0;

	double average_wait_time;

	for(int i=1;i<105;i++)
	{

		turnaways=0;
		customers=0;
		served=0;
		sum_line=0;
		wait_time=0;
		line_wait=0;

		perhour=i;
	min_per_cust=MIN_PER_HR/perhour;
	for(int cycle=0;cycle<cyclelimit;cycle++)
	{
		if(newcustomer(min_per_cust))//判斷有無新使用者
		{
			if(line.isfull())
				turnaways++;
			else
			{
				customers++;
//				cout<<"插入一個新客戶"<<endl;
				temp.set(cycle);//使用者到達時間
				line.insertqueue(temp);//插入新使用者

				
//				cout<<"現在時間"<<cycle<<endl;
//				cout<<customers<<"處理時間"<<temp.ptime()<<endl;

//				cout<<customers<<"位置:"<<line.CusNumbefore(temp)<<endl;
//				cout<<"wait_time="<<wait_time<<endl;
//				cout<<customers<<"等待時間:"<<(line.wait_time_min(temp,cycle)+wait_time)<<endl;
			}
		}
		if((wait_time<=0)&&!(line.isempty()))
		{
	//		cout<<"刪除一個客戶"<<endl;
			line.deletequeue(temp);
			line.set_first_start_time(cycle);
			wait_time=temp.ptime();
			line_wait+=cycle-temp.when();
			served++;
		}
		if(wait_time>0)
			wait_time--;
		sum_line+=line.queuecount();

		

//		cout<<"ATM執行時間結束"<<endl;

	}
	

	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";
		average_wait_time=(double)(line_wait/served);
		if(average_wait_time<=1)
		{
			cout<<perhour<<endl;
	//		break;
		}

		
		line.clearline();//清空佇列

	}
	else
		cout<<"No customers!\n";

	
	
	}
	cout<<"Done!\n";

}

void bank1()	
{	
	srand(time(0));
	cout<<"Case Study:Bank of Heather Automatic Teller\n";
//	cout<<"Enter maximum size of queue:";
	int qs;
//	cin>>qs;
	qs=10;
	Queue line1(qs);//輸入佇列最大長度
	Queue line2(qs);

//	cout<<"Enter the number of simulation hours:";

	int hours;
//	cin>>hours;
	hours=100;
	long cyclelimit=MIN_PER_HR*hours;//輸入程式執行時間

//	cout<<"Enter the average number of customers per hour:";
	double perhour;
//	cin>>perhour;//輸入每小時到達的客戶數
	double min_per_cust;

	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;

	double average_wait_time;

	for(int i=1;i<100;i++)
	{

		turnaways=0;
		customers=0;
		served=0;
		sum_line=0;
		wait_time1=0;
		wait_time2=0;
		line_wait=0;

		perhour=i;
	min_per_cust=MIN_PER_HR/perhour;
	for(int cycle=0;cycle<cyclelimit;cycle++)
	{
		if(newcustomer(min_per_cust))//判斷有無新使用者
		{
			if(line1.isfull()&&line2.isfull())
				turnaways++;
			else
			{
				customers++;
//				cout<<"插入一個新客戶"<<endl;
				temp.set(cycle);//使用者到達時間
//				cout<<line1.queuecount()<<endl;
//				cout<<line2.queuecount()<<endl;
				if(line1.queuecount()<=line2.queuecount())
				{
//					cout<<"line1插入一個新客戶"<<endl;
					line1.insertqueue(temp);//當line1的佇列人數小於等於line2時,向line1插入新使用者
				}
				else
				{
//					cout<<"line2插入一個新客戶"<<endl;
					line2.insertqueue(temp);//否則,向line2插入新使用者
				}
				
//				cout<<"現在時間"<<cycle<<endl;
//				cout<<customers<<"處理時間"<<temp.ptime()<<endl;

//				cout<<customers<<"位置:"<<line.CusNumbefore(temp)<<endl;
//				cout<<"wait_time="<<wait_time<<endl;
//				cout<<customers<<"等待時間:"<<(line.wait_time_min(temp,cycle)+wait_time)<<endl;
			}
		}
		if((wait_time1<=0)&&!(line1.isempty()))//處理line1的在隊首的客戶
		{
//			cout<<"line1刪除一個客戶"<<endl;
			line1.deletequeue(temp);
			line1.set_first_start_time(cycle);
			wait_time1=temp.ptime();
			line_wait+=cycle-temp.when();
			served++;
		}
		
		if((wait_time2<=0)&&!(line2.isempty()))//處理line2的在隊首的客戶
		{
	//		cout<<"line2刪除一個客戶"<<endl;
			line2.deletequeue(temp);
			line2.set_first_start_time(cycle);
			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();

		

//		cout<<"ATM執行時間結束"<<endl;

	}
	

	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";
		average_wait_time=(double)(line_wait/served);
		if(average_wait_time<=1)
		{
			cout<<perhour<<endl;
	//		break;
		}

		
		line1.clearline();//清空佇列
		line2.clearline();//清空佇列

	}
	else
		cout<<"No customers!\n";

	
	
	}
	cout<<"Done!\n";

}