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

来源:互联网 发布:黄磊人设崩塌 知乎 编辑:程序博客网 时间:2024/05/16 08:56
//queue.h#ifndef QUEUE__H__#define QUEUE__H__//This quene will contain Customer itemsclass 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 methodsQueue::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 queuebool 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);}