C.Primer.Plus(第六版)第12章 队列模拟

//queue.h
#ifndef QUEUE__H__
#define QUEUE__H__
//This quene will contain Customer items
class Customer
{
private:
    long arrive;// arrival time for customer
    int processtime;//processing time for customer 交易时间
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:
    enum{Q_SIZE = 10};
    struct Node
    {
        Item item;
        struct Node* next;
    };
    //private class members
    Node* front; //pointer to front of Quene
    Node* rear;  //pointer to rear of Quene
    int items;   //current number of items in Queue
    const int qsize;  // maximum number of items in Queue
    Queue(const Queue & q) : qsize(0){}//member initialization list 成员初始化列表
    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
//quene.cpp
#include <cstdlib>
#include "queue.h"

//Queue methods
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;
}
//Add item to queue
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;
    else 
        rear->next = add;
    rear = add;
    return true;    
}
bool Queue::dequeue( Item & item)
{
    if(isempty())
        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  using the Queue interface
#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;
    //setting things up
    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;//测试时间
    // simulation will run 1 cycle per minute
    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;// new customer data 
    long turnaways = 0;//turned away by full queue 被拒绝的客户
    long customers = 0;//joined the queue
    long served = 0;//served during the simulation  服务人数
    long sum_line = 0;//cumulative line lentgth 累计长度
    int wait_time = 0;//time until autoteller is free
    long line_wait = 0;//cumulative time in line
    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++;
        }
        //  先将数据保存,释放结点,再判断wait_time,可以理解为如果排队到第一个位置,则进入一个特殊的房间而不在队列中,但操作时间是从这时算起的(对后面排队的而言)。
        //上面的逻辑大致是这样的,第一次,首先,如果前面已经有客户入队了,那么这时if判断是都满足(wait_time时间初始化为0且队列也不为空),进入if,
        //这个时候的出队操作的思路是这样的,首先将头结点(p1)的客户数据取出来放在temp中,然后释放头结点(p1),(注意,temp对象仍存在),front指针指向下一个结点,即新的头结点(p2)。
        //但wait_time为被释放掉头结点(p1)的等候时间(保存在temp中)。
        //执行循环当wait_time再次为零时(默认有客户),进入if判断,再次出队,front指针指向头结点(p3),这时wait_time为头结点(p2)的等候时间....以此循环。
        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);
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值