C Primer Plus书中代码注释-ATM Quene队列模拟

ATM Queue模拟

#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));			//srand(time(0)),初始化时间种子 
	
	cout << "Case Study: Bank of Heather Automatic Teller\n";
	cout << "Enter maximum size of queue: ";
	int qs;			//qs队列的最大长度 
	cin >> qs;
	Queue line(qs);
	
	cout << "Enter the number of simulation hours: ";
	int hours;							//模拟时间 h 
	cin >> hours;
	
	long cyclelimit = MIN_PER_HR * hours;	//模拟时间min 
	
	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 << "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);
}
#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:
		//private representation to be developed later
		struct Node {	//链表更适合用于描述队列
						//C++特性:在类中嵌套结构(或类声明),Node作用域为整个类	
			Item item;
			struct Node * next; 
		};
		
		enum {Q_SIZE = 10
		};
		
		Node * front;
		Node * rear;
		
		int items;
		const int qsize;		//qsize是常量,可以对它进行初始化,但不能给它赋值(初始化之后不变) 
		
		Queue(const Queue & q): qsize(0){}
		Queue & operator=(const Queue & q) { return *this;}	//赋值运算符重载 
		
	public:
		Queue(int qs = Q_SIZE);		//constructor 
		~Queue();
		bool isempty() const;
		bool isfull() const;
		int queuecount() const;
		bool enqueue(const Item &item);
		bool dequeue(Item &item);
};

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

Queue::Queue(int qs) : qsize(qs)		//初始化类成员默认值,可用列表初始化,也可以函数体初始化。
										//列表初始化效率更高,但是不能初始化const变量 
{
	front = rear = NULL;
	items = 0;
}

Queue::~Queue()
{
	Node * temp;
	while(front != NULL){
		temp = front;
		front = front->next;	//front是一个指向Node结构的指针,Node里又定义了一个指向Node的指针next 
		delete temp;			//队列从前往后删除 
	}
}

bool Queue::isempty() const		//判断队列是否为空,如果是空items为0(两个等号),没人,等价于true 
{
	return items == 0;
}

bool Queue::isfull() const		//判断队列是否为full,如果是qsize,返回true 
{
	return items == qsize;
}

int Queue::queuecount() const	 
{
	return items;
}
 
bool Queue::enqueue(const Item & item)	//从后面添加元素 
{
	if(isfull())
		return false;			//如果队列满了,返回false 
	Node * add = new Node;		//创建add指针,这个指针指向一个动态分配的Node空间 
	
	add->item = item;			//向add指针指向的结构里的item添加customer 
	add->next = NULL;			//把add指针指向的结构里的结构指针next置为NULL,标志着队列的结尾,
								//如果向队列中添加元素(customer),就再新建一个“add”指针,链式赋值 
	items++;					//更新全局变量items,这是当前队列的customer 
	if(front == NULL)			//向指针front添加元素(customer),如果front是NULL,add就是front的地址 
		front = add;
	else						//如果front不为空,则把add的地址添加到rear指针 
		rear->next = add;		//指针rear指向next的地址,rear是队列中最后一个元素,
								//这里就是在队列的最后面添加元素,rear和rear->next都指向新加入元素的地址 
								 
	rear = add;					//把指针rear也指向add的地址 
	return true;
}

bool Queue::dequeue(Item & item)//这是从前向后删除队列中的元素 
{
	if(front == NULL)			//如果队列为空,返回false 
		return false;
	item = front->item;			//队列不为空(返回true),让item指向front的首个元素 
	items--;
	Node * temp = front;		//把front地址赋给temp 
	front = front->next;		//把front的next地址赋值给front 
	delete temp;				//删除front,就是删除了队列的前端数据 
	if(items == 0)				//如果队列为空,把rear置为NULL
		rear = NULL;
	return true;
}

void Customer::set(long when)
{
	processtime = std::rand() % 3 + 1;
	arrive = when;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值