The Bank Queue Problem

Pages: 12
Looking for advice. This simulation has 4 header files and one main. I need two int arrays to save some calculations that take place within two functions. I will use those arrays (I think) to calculate the average waiting time the customers have spent waiting in line. The two function definitions come after the main function. Let me know if I should post the header files. I created three of the .h files as previous homework assignments. Thank you all for who help :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  //Phase II Testing Program
#include<iostream>
#include"DataElement.h"
#include"SortedList.h"
#include"Event.h"
#include"Queue.h"
using namespace std;

const int SIZE = 6;

void processArrival(int& customer, DataElement  iFile[], int  length, SortedList<Event>& eList, Queue<DataElement>& bQueue);
void processDeparture(SortedList<Event>& eList, Queue<DataElement>& bQueue, int& wTime);

int main()
{
	//Set up an array of DataElement with the data the bank provided:
	DataElement bankData[SIZE] = { DataElement(20,5), DataElement(22,4), DataElement(23,2), DataElement(30,3), DataElement(40,3), DataElement(41,4) };
	
	Queue<DataElement> bankQueue;//Declare an instance of class template Queue
	SortedList<Event> eventList;//Declares an instance of class template List

	int customer = 0;
	int waitingTime;
	int counter = 1;
	int totalWaitingTime = 0;

	//Create an array to save waiting time and transaction begin time and just add them both above



	  //Testing the function processArrial():
	Event aEvent1('A', 20);  //create an arrival event
	eventList.insertSorted(aEvent1); //insert above arrival event into eventList
	char eStatus = eventList.getEntry(1).getEventStatus();

	while (!eventList.isEmpty())
	{
		char eStatus = eventList.getEntry(1).getEventStatus(); // Saves the event status of an event at position one
		if (eStatus == 'A')
		{
			processArrival(customer, bankData, SIZE, eventList, bankQueue);// Function Call
			customer++;
		}
		else
		{
			processDeparture(eventList, bankQueue, waitingTime);
		}
	}

	system("pause");
	return 0;
}
void processArrival(int& customer, DataElement iFile[], int length, SortedList<Event>& eList, Queue<DataElement>& bQueue)
{
	// Check if the bankQueue is empty
	if (bQueue.isEmpty())
	{
		Event eDeparture;
		eDeparture.setEventStatus('D'); //Sets the event status
		int dOccurrence = iFile[customer].getArrivalTime() + iFile[customer].getTransactionTime(); //Occurrence of the departure
		// I want to create an array of int dOccurrence[15] to store all the dOccurrence times

		eDeparture.setOccurTime(dOccurrence); //Sets the Occurrence time of the departure
		eList.insertSorted(eDeparture); // Added Departure event to eList... using the address of operator, so will this value make it out to the main function?
	}
	// insert a customer into the bQueue
	bQueue.enqueue(iFile[customer]); // Do i start at one? since i added customer 0 already who is also already seeing the teller
	eList.remove(1);// does this delete the newest arrival event
	if (customer != length - 1)
	{
		Event aEvent;
		aEvent.setEventStatus('A');
		int aOccurrence = iFile[customer + 1].getArrivalTime();
		aEvent.setOccurTime(aOccurrence);
		// to create an array of aOccurrence times can should I use a struct with two int data variables to store aOccurrence and Customer sub 0,1,2,3...
		// int aOccurrence = iFile[customer + 1].getArrivalTime() + iFile[customer + 1].getTransactionTime();
	}
}

void processDeparture(SortedList<Event>& eList, Queue<DataElement>& bQueue, int& wTime)
{
	bQueue.dequeue();
	if (!bQueue.isEmpty())
	{
		//eList.getEntry(1).getOccurTime(); // accesses the list at entry 1, then uses the . operator to get its OccurTime of departur;
		Event dEvent('D', eList.getEntry(1).getOccurTime() + bQueue.peekFront().getTransactionTime());
		eList.insertSorted(dEvent);
		wTime = eList.getEntry(1).getOccurTime() - bQueue.peekFront().getArrivalTime();
	}
	else
	{
		wTime = 0;
	}
	eList.remove(1);
}
Last edited on
What kind of help are you looking for? Is there any behavior of your program that doesn't meet your expectations?
Hello mdh1559,

Let me know if I should post the header files.



Yes. It is always helpful to include all files and code that will allow a program to compile. Also someone may see something in a header file that is a problem or potential problem.

A couple of notes:

In lines 22 - 25 you define variables and initialize 3 of them. It is best, if not for the peace of mind, to initialize all the variables. In this case it does not make any difference because the function you pass it to gives it a value.
On line 41 you pass the variable "SIZE" and then on line 53 the function gives it another name. "SIZE" is defined as a global variable which has file scope. There is not need to pass it to the function just use it. "length - 1" is the same as "SIZE - 1" and will work the same as the "- 1" does not change the value of the variable it just makes it one less.

For me just reading the program is not enough I like to run the program with break points to see exactly what variables contain at different points in the run.

Hope that helps,

Andy
Let me respond with a question for you: Do I have enough gas in my car?

You probably blinked and thought "well how the heck should I know? You didn't say how much gas you have, or how far you're traveling, or what sort of mileage you get"

Your question is sort of like asking us if you have enough gas. We can't see the whole program and we don't know what it's supposed to do, so we can't say if it's working correctly.

When processing an arrival, why do you only create a departure event if the bQueue is empty? Don't all customers who arrive eventually leave?

When I write simulators, I structure them like this. It makes for very tight and easy to read code.

There's a simulator class. This has a collection of events, the simulator time, and whatever other info is related to the state of the simulation. In your case, it's info about the bank and customers.

There's a separate Event base class. It has a virtual process() method that takes a reference to the simulator:
virtual void process(Simulator &);
Ideally, that's an abstract method, but since this is the beginners forum, I'll assume you haven't studied that yet.

Each "real" type of event is derived from the Event class and implements the process() method. For example, you'd have an Arrive class derived from Event. It's process() method would contain the code currently in ProcessArrival.

And data that a process() method needs should be a member of the simulator or the derived event.

Back at the simulator class, it has a run() method that basically does:
1
2
3
4
while (!eventQueue.empty()) {
    eventQueue.front().process(*this);
    eventQueue.popFront();
}
@dhayden,

I like the gas part. I will have to remember that.

Andy
#ifndef _DATAELEMENT
#define _DATAELEMENT
#include <iostream>
using namespace std;

class DataElement
{
private:
int arrivalTime;
int transactionTime;
public:
DataElement();// Default Constructor
DataElement(int arTime, int teaTime); // Non-Default Constructor
void setArrivalTime(int arTime);//#1
int getArrivalTime();// #2
void setTransactionTime(int teaTime);// #3
int getTransactionTime();// #4
friend ostream& operator<<(ostream& out, const DataElement& thing);// Overloaded operator #5
};
// Overloaded cout <<
ostream& operator<<(ostream& out, const DataElement& thing)
{
out << " arrivalTime is " << thing.arrivalTime << " transaction time is " << thing.transactionTime;
return out;
}
// Default Constructor, time zero
DataElement::DataElement()
{
arrivalTime = 0;
transactionTime = 0;
}
// Non Default Constructor. Does this information come from an external file? What is that files name?
DataElement::DataElement(int arTime, int teaTime)
{
arrivalTime = arTime;
transactionTime = teaTime;
}
// setArrivalTime
void DataElement::setArrivalTime(int arTime)// #1
{
arrivalTime = arTime;
}
// getArrivalTime
int DataElement::getArrivalTime()// #2
{
return arrivalTime;
}
// setTransactionTime
void DataElement::setTransactionTime(int teaTime)// #3
{
transactionTime = teaTime;
}
// getTransactionTime
int DataElement::getTransactionTime()// #4
{
return transactionTime;
}
#endif
#ifndef _SORTED_LIST
#define _SORTED_LIST
#include<iostream>
#include"Node.h"
using namespace std;

template<class ItemType>
class SortedList
{
private:
Node<ItemType>* head;
int itemCount; //Current count of list items
Node<ItemType>* getNodeBefore(const ItemType& anEntry)const; //use for remove sorted
Node<ItemType>* getNodeAt(int position) const; //Return a pointer that holds the address of the node at 'position'
public:
SortedList(); //#1 Default constructor
SortedList(const SortedList<ItemType>& aList); //#2 Copy constructor
bool isEmpty() const; //#3 Check if the list empty (no item stored in the array)
int getLength() const; //#4 Returns the number of items in the list
bool remove(int position); //#5 Remove an entry at given position from the list
void clear(); //#6 remove all the items from the list
ItemType getEntry(int position) const; //#7 Retrieves an item on the list at the given position
void displayList(); //#8


//Following are three new methods:
void insertSorted(const ItemType& newEntry); //#9
bool removeSorted(const ItemType& anEntry); //#10
int getPosition(const ItemType& newEntry) const; //#11
};

// Private member function #1
template <class ItemType>
Node<ItemType>* SortedList<ItemType>::getNodeBefore(const ItemType& anEntry)const // head->(item)(Ptr)->(item)(Ptr)-->>NULL
{
Node<ItemType>* currNode = head;
// If the list is empty
if (currNode == NULL)
return NULL;
// List is not empty
Node<ItemType>* preNode = currNode;
while (currNode != NULL)
{
if (!isEmpty() && anEntry < head->getItem() && preNode == NULL)
{
return NULL; // List is not empty BUT anEntry must go before the first node
}
if (currNode->getItem() >= anEntry)
{
return preNode;
}
preNode = currNode;
currNode = currNode->getNext();
}
if (preNode == currNode)
{
return NULL;
}
return preNode; /* If the while loop was broken with a break statement and then preNode == currNode then
that must mean that*/
}

// Private member function #2
template <class ItemType>
Node<ItemType>* SortedList<ItemType>::getNodeAt(int position) const
{
if (position < 1 || position > itemCount)
{
cout << "That is an invalid position" << endl;
}
Node<ItemType>* currNode = head;
if (currNode == NULL)
{
cout << "The list is empty." << endl;
return NULL;
}
// traverse the list
for (int a = 1; a < position; a++)
currNode = currNode->getNext();
return currNode;
}

// #1
template <class ItemType>
SortedList<ItemType>::SortedList()
{
head = NULL;
itemCount = 0;
}

// #2
template <class ItemType>
SortedList<ItemType>::SortedList(const SortedList<ItemType>& aList)
{

itemCount = aList.itemCount;
Node<ItemType>* current = aList.head->getNext();
Node<ItemType>* iterator = head = new Node<ItemType>(aList.head->getItem(), NULL);
while (current != NULL)
{
iterator->setNext(new Node<ItemType>(current->getItem(), NULL));

current = current->getNext();
iterator = iterator->getNext();
}
}
// #3
template <class ItemType>
bool SortedList<ItemType>::isEmpty() const
{
if (head == NULL)
return true;
return false;
}

// #4
template <class ItemType>
int SortedList<ItemType>::getLength() const
{
return itemCount;
}

// #5
template <class ItemType>
bool SortedList<ItemType>::remove(int position)
{
if (isEmpty())
{
cout << "The list is empty." << endl;
return false;
}
Node<ItemType>* currNode = NULL;
// If position is equal to 1. User wants to remove the first
if (position == 1)
{
currNode = head;
head = head->getNext();
}
else
{
// preNode will now tril currNode
Node<ItemType>* preNode = getNodeAt(position - 1);
// currNode will now point to the target
currNode = preNode->getNext();
// break the chain
preNode->setNext(currNode->getNext());
}
// Free memory from currNode
currNode->setNext(NULL);
delete(currNode);
currNode = NULL;
// Decrement itemCount
itemCount--;
return true;
}

// #6
template<class ItemType>
void SortedList<ItemType>::clear()
{
while (!isEmpty())
{
remove(1);
}
}

// #7
template<class ItemType>
ItemType SortedList<ItemType>::getEntry(int position) const
{
Node<ItemType>* currPtr = head;
if (position<1 || position>itemCount)
{//exit(1); // when it is return 0, it says 'return': cannot convert from 'int' to 'Event'
cout << "Fatal error" << endl;
}
for (int i = 1; i < position; i++)
currPtr = currPtr->getNext();

return currPtr->getItem();

}

// #8
template<class ItemType>
void SortedList<ItemType>::displayList()
{
Node<ItemType>* currPtr = head;
if (currPtr == NULL)
{
cout << "It is an empty list." << endl;
}

while (currPtr != NULL)
{
cout << currPtr->getItem() << endl;
currPtr = currPtr->getNext();
}
}
template<class ItemType>
void SortedList<ItemType>::insertSorted(const ItemType& newEntry) // #9
{
Node<ItemType>* newNode, * currNode, * preNode = NULL;
bool flag;
newNode = new Node<ItemType>(newEntry);
if (head == NULL)
{
newNode->setNext(head);
head = newNode;
newNode = NULL;
delete(newNode);
}
else
{
currNode = head;
flag = false;
// Traverse the list
while (currNode != NULL && !flag)
{
if (currNode->getItem() >= newEntry)
flag = true;
else
{
preNode = currNode;
currNode = currNode->getNext();
}
}

if (currNode == head) // if true then newEntry is the smallest and must be inserted at position 1
{
newNode->setNext(head);
head = newNode;
// increment the itemcount
//itemCount++;
}
else
{
preNode->setNext(newNode); // newEntry goes somewhere in the list other than position 1
newNode->setNext(currNode);

if (currNode == NULL)
newNode->setNext(NULL);

//itemCount++;
}
}
itemCount++;
}

template<class ItemType>
bool SortedList<ItemType>::removeSorted(const ItemType& anEntry) // #10
{
Node<ItemType>* currNode, * preNode = NULL;

if (head == NULL)
{
return false;
}

if (head->getItem() == anEntry)
{
currNode = head;
head = head->getNext();
currNode = NULL;
delete(currNode);
itemCount--;
return true;
}
else
{
currNode = head;
while (currNode != NULL && currNode->getItem() != anEntry)
{
//getNodeBefore
preNode = currNode;
currNode = currNode->getNext();
}

if (currNode)
{
preNode->setNext(currNode->getNext());
delete(currNode);
itemCount--;
return true;
}
}
return false;

}

template<class ItemType>
int SortedList<ItemType>::getPosition(const ItemType& newEntry) const // #11 to return a postion to input
{
Node<ItemType>* currNode = head; // if current node equals NULL? do I return zero?

int iCount = 0; // Variable to return before the function ends

while (currNode != NULL)
{
if (head->getItem() == newEntry)
{
return ++iCount;
}
else if (currNode->getItem() >= newEntry)
{

return ++iCount;
}
else
{
currNode = currNode->getNext();
iCount++;
}
}
// While loop has been broken
if (currNode == NULL)//List had been exhausted,
{
return ++iCount;
}
return iCount;
}
#endif
//header file for the template class Node
#ifndef _NODE
#define _NODE

template<class ItemType>
class Node
{
private:
ItemType item;
Node<ItemType> *next;
public:
Node(); //default constructor
Node(const ItemType &anItem);//none default constructor
Node(const ItemType &anItem, Node<ItemType> *nextPtr); //none default constructor
void setItem(const ItemType &anItem);
void setNext(Node<ItemType> *nextPtr);
ItemType getItem() const;
Node<ItemType> *getNext() const;
};
template<class ItemType>
Node<ItemType>::Node()
{
next = NULL;
}
template<class ItemType>
Node<ItemType>::Node(const ItemType &anItem)
{
item = anItem;
next = NULL;
}
template<class ItemType>
Node<ItemType>::Node(const ItemType &anItem, Node<ItemType> *nextPtr)
{
item = anItem;
next = nextPtr;
}
template<class ItemType>
void Node<ItemType>::setItem(const ItemType &anItem)
{
item = anItem;
}
template<class ItemType>
void Node<ItemType>::setNext(Node<ItemType> *nextPtr)
{
next = nextPtr;
}
template<class ItemType>
ItemType Node<ItemType>::getItem() const
{
return item;
}
template<class ItemType>
Node<ItemType>* Node<ItemType>::getNext() const
{
return next;
}
#endif
// Page 539 Daniel Liang Overloading stream insertion operator
#ifndef _Event
#define _Event
using namespace std;
#include <iostream>

class Event
{
private:
char eventStatus;
int occurTime;
public:
Event();// #1
Event(char eStatus, int oTime);// #2
void setEventStatus(char eStatus);// #3
char getEventStatus();// #4
void setOccurTime(int oTime);// #5
int getOccurTime();// #6
// Over Operators
bool operator >=(const Event& anEvent)const;
bool operator>(const Event& anEvent) const;// #7
bool operator==(const Event& rightHandObject) const;// #8
friend ostream& operator<<(ostream& out, const Event &thing);// #9
};
// OVERLOADED functions
bool Event::operator>=(const Event& anEvent) const
{
if (this->occurTime >= anEvent.occurTime)
return true;
return false;
}
bool Event::operator>(const Event& anEvent) const// #7
{
if (this->occurTime > anEvent.occurTime)//occurTime. && eventStatus
{
return true;
}
return false;
}

bool Event::operator==(const Event& rightHandObject) const// #8
{
if (this->occurTime == rightHandObject.occurTime)
return true;
else
return false;
}

ostream& operator<<(ostream& out, const Event &thing)// #9
{
out << " Event Status " << thing.eventStatus << " Occur Time " << thing.occurTime;
return out;
}

Event::Event()// #1
{
eventStatus = 0;
occurTime = 0;
}
Event::Event(char eStatus, int oTime)// #2
{
eventStatus = eStatus;
occurTime = oTime;
}
void Event::setEventStatus(char eStatus)// #3
{
eventStatus = eStatus;
}
char Event::getEventStatus()// #4
{
return eventStatus;
}
void Event::setOccurTime(int oTime)// #5
{
occurTime = oTime;
}
int Event::getOccurTime()// #6
{
return occurTime;
}
#endif
//Header File of Class Template for ADT Queue
#ifndef _QUEUE
#define _QUEUE
#include <iostream>
#include"Node.h"
using namespace std;

template<class ItemType>
class Queue
{
private:
Node<ItemType> *backPtr;
Node<ItemType> *frontPtr;

public:
Queue(); //Default constructor #1
Queue(const Queue<ItemType> &aQueue); //Copy constructor #2

bool isEmpty() const; //#3
bool enqueue(const ItemType &newEntry); //#4
bool dequeue(); //#5
ItemType peekFront() const; //#6
void display()const; //#7
};

template<class ItemType>
Queue<ItemType>::Queue() //#1
{
frontPtr = NULL;
backPtr = NULL;
}

template<class ItemType>
Queue<ItemType>::Queue(const Queue<ItemType>& aQueue) // #2
{
Node<ItemType> *originalNodePtr = aQueue.frontPtr;
if (originalNodePtr == NULL) {
frontPtr = NULL;
backPtr = NULL;
}
else {
//copy the first node
frontPtr = new Node<ItemType>;
frontPtr->setItem(originalNodePtr->getItem());
//copy the remaining nodes
backPtr = frontPtr;
while (originalNodePtr->getNext() != NULL)
{
originalNodePtr = originalNodePtr->getNext();
ItemType nextItem = originalNodePtr->getItem();
Node<ItemType> *newNode = new Node<ItemType>(nextItem);
backPtr->setNext(newNode);
backPtr = backPtr->getNext();
}
backPtr->setNext(NULL);
}
}

template<class ItemType>
bool Queue<ItemType>::isEmpty() const // #3
{
if (frontPtr == NULL && backPtr == NULL)
{
return true;
}
else
{
return false;
}
}
template<class ItemType>
bool Queue<ItemType>::enqueue(const ItemType &newEntry)//(N-Q)Enqueue, add node to rear #4
{
// Meomory allocation, malloc for new Node and assign it to *newNode
Node<ItemType> * newNode = new Node<ItemType>(newEntry, NULL);
// Think about an empty Queue first
if (isEmpty())
{
frontPtr = backPtr = newNode;
newNode = NULL;
delete(newNode);
return true;
}
// Not an empty Queue
backPtr->setNext(newNode);
backPtr = backPtr->getNext();
newNode = NULL;
delete(newNode);
return true;
}
template<class ItemType>
bool Queue<ItemType>::dequeue() // #5
{
Node<ItemType> * currentPointer = frontPtr;
// If list is empty, do I have to consider this case??? Ask someone
if (isEmpty())
{
return false;
}
// If the two pointers equal each other then they must point to the same node
if (frontPtr->getNext() == backPtr->getNext())
{
frontPtr->setNext(NULL);
backPtr->setNext(NULL);
currentPointer->setNext(NULL);
delete(currentPointer);
return true;
}
else
{
// More than one node in the Queue
if (!isEmpty()) // if list is not empty ???
frontPtr = frontPtr->getNext();
currentPointer->setNext(NULL);
delete(currentPointer);
return true;
}
return false;

}

template<class ItemType>
ItemType Queue<ItemType>::peekFront() const // #6
{
if (isEmpty())
{
cout << "Fatal error occured!" << endl;
exit(1);
}
else
{
Node<ItemType> * currentPointer = frontPtr;
return currentPointer->getItem();
}
}

template<class ItemType>
void Queue<ItemType>::display() const // #6
{
if (isEmpty())
{
cout << "The list is empty dumbass!" << endl;
}
else
{
Node<ItemType> * currentPointer = frontPtr;
while (currentPointer != NULL)
{
cout << currentPointer->getItem() << endl;
currentPointer = currentPointer->getNext();
}
}
}
#endif
When the simulation has finished I will have to print out to the screen

#1 The customers arrival time (easy)
#2 Transaction start time (easy)
#3 Departure time (Not a big deal)
#4 Waiting time of each customer
#5 The average waiting time of all six customers

I already kind of figured out that I can use an int array that I will declare inside of function main to store customers wait time and transaction begin time. I will use the customers time spent waiting in line to calculate the average waiting time. I will us the transaction begin time to print out to the screen.
coder777, handAndy, and dHayden. I have read your comments and appreciate the time you three have taken to read my post. I am looking more in to my assignment and will post more specific questions soon. Thank you three very much.
Thanks for posting the code. I got it to run, but I'm not sure if it's doing what it should. Can you explain the assignment?

Here are my comments and changes. Since the code is large, I've included just the parts that I commented on. See the comments that start with "DMH" or "dmh"
1
2
3
4
5
6
// Private member function #1
// DMH - how do you distinguish between anEntry < head and
// anEntry > lastItem?  In both cases you appear to return NULL
template < class ItemType >
Node < ItemType > *
SortedList < ItemType >::getNodeBefore(const ItemType & anEntry) const  // head->(item)(Ptr)->(item)(Ptr)-->>NULL 



1
2
3
4
5
// Private member function #2
// DMH, so position 1 is the first item. In C++, usually positions start at zero.
template < class ItemType >
Node < ItemType > *
SortedList < ItemType >::getNodeAt(int position) const

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// #2
template < class ItemType >
SortedList < ItemType >::SortedList(const SortedList < ItemType > &aList)
{
#if 0
    // DMH - Doesn't handle the case where aList is empty
    itemCount = aList.itemCount;
    Node < ItemType > *current = aList.head->getNext();
    Node < ItemType > *iterator = head = new Node < ItemType > (aList.head->getItem(), NULL);
    while (current != NULL) {
        iterator->setNext(new Node < ItemType > (current->getItem(), NULL));

        current = current->getNext();
        iterator = iterator->getNext();
    }
#else
    itemCount = aList.itemCount;
    if (aList.head == NULL) {
        head = NULL;
    } else {
        head = new Node<ItemType>(head->getItem());
        Node < ItemType > *src, *prev = head;
        for (src = aList.head->getNext(); src; src = src->getNext()) {
            prev->setNext(new Node<ItemType>(src->getItem()));
            prev = prev->getNext();
        }
    }
#endif
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template < class ItemType >
ItemType
SortedList < ItemType >::getEntry(int position) const
{
    Node < ItemType > *currPtr = head;
    if (position < 1 || position > itemCount) {  //exit(1); // when it is return 0, it says 'return': cannot convert from 'int' to 'Event'
        cout << "Fatal error" << endl;
    }
    // dmh: why not currPtr = getNodeAt(position);
    for (int i = 1; i < position; i++)
        currPtr = currPtr->getNext();

    return currPtr->getItem();

}


In insertSorted()
1
2
3
4
5
6
7
        newNode = NULL;
        delete(newNode);        // DMH delete(NULL), so code has no effect. Besides, you don't want to delete the new node
...
            newNode->setNext(currNode);

            if (currNode == NULL)
                newNode->setNext(NULL); // DMH Code has no effect because the setNext() above did this. 


In getPosition:
1
2
3
4
5
6
    // While loop has been broken
    // DMH the condition below is always true
    if (currNode == NULL)                        //List had been exhausted,
    {
        return ++iCount;
    }


In enqueue (occurs twice):
1
2
        newNode = NULL;
        delete(newNode);        // dmh code has no effect because newNode== NULL. Besides, you don't want to delete it 


Here's the biggest bug. It's in dequeue:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    // If the two pointers equal each other then they must point to the same node
    // dmh - why not just frontPtr == backPtr?
    // Also, when deleting the only item, you must set both pointers to NULL
    if (frontPtr->getNext() == backPtr->getNext()) {
#if 0
        frontPtr->setNext(NULL);
        backPtr->setNext(NULL);
        currentPointer->setNext(NULL);
        delete(currentPointer); // dmh code has no effect. Delete the line above
#else
        delete currentPointer;
        frontPtr = backPtr = NULL;
#endif

In processArrival:
[code]    // DMH - changed from length-1 to length-2
    if (customer != length - 2) {
        Event aEvent;
        aEvent.setEventStatus('A');
        int aOccurrence = iFile[customer + 1].getArrivalTime();


[/code]
(anEntry < head->getItem()) and (anEntry < currNode->getItem()) ? if currNode->getNext() is equal to NULL that means that currNode is pointer to the last Node in the list. if currNode is actually pointing to NULL then that means preNode is pointing to the last node, preNode has the address of the last node. This stuff is hard to communicate through text.
Assume we receive a set of data from a bank which contains a list of arrival times and transaction times of the customers who visited the bank during a specific period of time. For example, a sample data may be provided as following:

Arrival Time: Transaction Time:
20 5
22 4
23 2
30 3
40 3
41 4
-------------------------------------------------------------------

Write a C++ program that can be used to process the data and calculates/displays

The time each customer arrive the bank
The time each customer begins the transaction
The time each customer leaves the bank
The waiting time of each customer
The average waiting time of all the customers in this period of time.
that is the question so that is what this bankQueue simulation should do. I am actually kind of stuck right now and will be spending some time walking through what this simulation should do on paper. I used the debugger for a bit but still confusing. I just set a break point at the process arrival function and used the step into f11 key to check out the variables. I think if i just go through the logic on paper a number of times I will be able to transfer all the steps over to code later.
Last edited on
I'm sorry to say this, but I think there's a much easier solution to this problem. You need these variables:
1
2
3
4
5
    int transStartTime = 0;   // start time of next transaction
    int entryTime;            // customer entry time
    int duration;             // duration of customer's transaction
    int totalWaitTime;        // total wait time of customers
    int numCustomers=0;       // number of customers 


The key here is transStartTime. It records when the bank teller will be available to start the next transaction. Now set up a while loop to read the entry time and duration from each line of the input. Then:
- If the customer arrives after the transStartTime, then change transStartTime to the customer arrival time. After all, the teller can't start the transaction before the customer arrives!

Now you can print out the info for this customer's transaction:
You read the entry time from the input.
The wait time is the transStartTime - entryTime
The transaction starts at transStartTime
The customer leaves at transStartTime+duration

After you print this stuff out, you need to update some of the variables:
- add one to numCustomers
- add this customer's wait time to totalWaitTime
- add the transaction duration to transStartTime to indicate that the teller is available when this transaction ends.

After you've read all the input, the average wait time is totalWaitTime / numCustomers.

It's less than 40 lines of code.
Two other things. Here is the output that I got:
Entry   Wait    Start   Exit
20      0       20      25
22      3       25      29
23      6       29      31
30      1       31      34
40      0       40      43
41      2       43      47

Average Wait time = 2


Second is a general thing about simulations that often trips up developers. Ready? Here it is:

The simulator can see into the future.

In this case, in the real world, you walk into the bank and you don't know how long the transactions will take. The only way to find out is to wait. In the simulator, you know and can take advantage of that.
How do I add pictures to the comments here? I finished the project but I had to ask a tutor for help at school. I've only been coding since January 2019 (this year). I had to ask how to use the variable counter and I thought I was going to have to pass some arrays as parameters in the process arrival function to extract the needed information. I guess i need to read more about the fundamentals of c++ and maybe use code signal to practice more?? Any advice on how to obtain a better understanding of C++?
The site doesn't directly support pictures. You must store it somewhere else and post a link to it.

You seem to have a decent understanding of C++, you just went in the wrong direction with this assignment. Here is the code that I came up with:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>

using namespace std;

int main()
{
    int transStartTime = 0;   // start time of next transaction
    int entryTime;	      // customer entry time
    int duration;	      // duration of customer's transaction
    int totalWaitTime;	      // total wait time of customers
    int numCustomers=0;	      // number of customers

    cout << "Entry\tWait\tStart\tExit\n";
    while (cin >> entryTime >> duration) {
	// If the customer arrives after the next available transaction
	// time then the transaction starts when the customer arrives
	if (transStartTime < entryTime) {
	    transStartTime = entryTime;
	}
	cout << entryTime << '\t'
	     << transStartTime-entryTime << '\t'
	     << transStartTime << '\t'
	     << transStartTime+duration << '\n';

	++numCustomers;
	totalWaitTime += transStartTime - entryTime;
	transStartTime += duration;
    }
    cout << '\n'
	 << "Average Wait time = "
	 << (double) totalWaitTime / numCustomers << '\n';
}


Any advice on how to obtain a better understanding of C++?
Practice solving problems. Also read other people's code. You might want to try projecteuler.net. Once you solve a problem, you have access to the solutions from other people.
Pages: 12