C++模拟ATM

下面代码实现的一个功能是模拟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 items
class Customer
{
private:
  long arrive; // arrive 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:
  //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 methods
Queue::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 queue
bool 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 queue
bool 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-3
void 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 minute
bool 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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值