C++模拟ATM

来源:互联网 发布:《大数据思维与决策》 编辑:程序博客网 时间:2024/05/24 15:35

下面代码实现的一个功能是模拟ATM,程序允许用户输入3个数据:队列的最大长度、程序模拟的持续时间(单位为小时)以及平均每小时的客户数。

在程序中,使用循环,每次循环代表一分钟,在每次循环中,程序将完成下面的工作
1.是否来新客户,来:队列未满,入队;队列已满,拒绝
2.如果没有客户进行交易,则取队列的第一个客户。确定客户的已等候时间,并将wait_time计数器设置为新客户所需的处理时间
3.如果客户正在处理中,则讲wait_time计数器减1.
4.记录各种数据,如获得服务的客户数目、被拒绝的客户数(满队情况)、排队等候的累计时间以及累积的队列长度等。

queue.h

//queue.h --interface for a queue#ifndef QUEUE_H_#define QUEUE_H_//This queue will contain Customer itemsclass Customer{private:  long arrive; // arrive time for customer  int processtime;//processing time for customerpublic:  Customer() {arrive = processtime = 0;}  void set(long when);  long when() const {return arrive;}  int ptime() const {return processtime; }};typedef Customer Item;class Queue{private:  //class scope definitions    //Node is a nested structure definition local to this c  struct Node{Item item; struct Node *next;};  enum {Q_SIZE = 10};  //private class members  Node * front; // pointer to front of Queue  Node * rear; // pointer to rear of Queue  int items; // current number of items in Queue  const int qsize; // maximum number of items in Queue  //preemptive definitions to prevent public copying  Queue(const Queue & q) : qsize(0) {}  Queue & operator = (const Queue & q) {return *this;}public:  Queue(int qs = Q_SIZE); // create queue with a qs limit  ~Queue();  bool isempty() const;  bool isfull() const;  int queuecount() const;  bool enqueue(const Item &item); // add item to end  bool dequeue(Item &item);};#endif

queue.cpp

//queue.cpp --Queue and Customer methods#include <cstdlib>#include "queue.h"//Queue methodsQueue::Queue(int qs) : qsize(qs){  front = rear = NULL; //or nullptr   items = 0;}Queue::~Queue(){  Node * temp;  while (front != NULL) //while the queue is not yet empty  {    temp = front; // save the address of front item    front = front->next;// reset pointer to next item    delete temp; // delete former front  }}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; // create node  // on failure, new throws std::bad_alloc exception  add->item = item; // set node pointers  add->next =NULL; // or nullptr  items++;  if(front == NULL) // if queue is empty    front = add; // place item at front  else    rear->next = add; // else place at rear  rear = add; // have rear point to new node  return true;}//place front item into item variable and remove from queuebool Queue::dequeue(Item& item){  if(front == NULL)      return false;  item = front->item; // set item to first item in queue  items--;  Node * temp = front; // save location of first item  front = front->next; // rest front to next item  delete temp; // delete former first item  if(items == 0)     rear = NULL;  return true;}//time set to a random value in  the range 1-3void Customer::set(long  when){  processtime = std::rand() % 3 + 1;  arrive = when;}

main.cpp

//main.cpp -- using the queue interface//compile with queue.cpp#include <iostream>#include <cstdlib> // for rand() and srand()#include <ctime> // for time()#include "queue.h"const int MIN_PER_HR = 60;bool newcustomer(double x); // is there a new customer?int main(int argc, char **argv) {    using  std::cin;    using  std::cout;    using  std::endl;    using  std::ios_base;    //set things up    std::srand(std::time(0)); //random initializing of rand()    cout << " Case study: Bank of Heather Automatic Teller \n";    cout << "Enter maximum size of queue: ";    int qs;    cin >> qs;    Queue line(qs); // line queue holds up to qs people    cout << "enter the number of simulation hours: ";    int hours; //hours of simulation    cin >> hours;    // simulation will run 1 cycle per minute    long cyclelimit = MIN_PER_HR * hours; // # of cycles    cout << "enter the average number of customer per hour :  ";    double perhour; //average # of arrival per hour    cin >> perhour;    double min_per_cust; //average time between arriavals    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 length    int wait_time = 0;// time until autoteller is free    long line_wait = 0;//cumulative time in line    //running the simulation    for(int cycle = 0; cycle < cyclelimit; cycle++)    {      if(newcustomer(min_per_cust))//have new customer      {    if(line.isfull())      turnaways++;    else{      customers++;      temp.set(cycle);//cycle = time of arrival      line.enqueue(temp);// add newcomer to line    }      }      if(wait_time <= 0 && !line.isempty())      {    line.dequeue(temp);//attend next customer    wait_time = temp.ptime();//for wait_time minutes    line_wait += cycle - temp.when();    served++;      }      if(wait_time > 0)    wait_time--;      sum_line += line.queuecount();    }    //reporting results    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 << (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;}//x = average time in minutes, between customers// return value is true if customer shoews up this minutebool newcustomer(double x){  return (std::rand() * x / RAND_MAX < 1);}

最后模拟的结果,如下图所示
这里写图片描述

可以看到如果一个小时客户的平均数量在15个时,拒绝的客户为0;等候时间也只有0.58min,但是如果将一个小时客户的平均数量设置在30个,等候的平均时间就会大大增加。这里因为采取随机数,所以每次结果可能会有一些不同。

同时,也练习了单链表的构建。链表是一种数据的存储方式,其保存的数据在内存中是不连续的,采用指针对数据进行访问,代码中这个写的非常清楚,而且也使用了很多次。

队列是一种数据结构,其特点是先进先出(正是因为如此,才特别符合ATM的模拟)。

参考书籍
Publishing S. C++ Primer Plus, Fifth Edition[J]. Pearson Schweiz Ag, 2005.