A AdditionProblem.h |
/*-- AdditionProblem.h ---------------------------------------------- This header file contains the declaration of class AdditionProblem. Basic operations: constructor: Generates problem with random addends -- uses random number generator rand() from cstdlib display(): Displays the problem answer(): Returns answer to problem --------------------------------------------------------------------*/ #include <iostream> #ifndef ADDITION_PROBLEM #define ADDITION_PROBLEM class AdditionProblem { public: /***** Function Members *****/ AdditionProblem(int maxAddend = 100); /*---------------------------------------------------------- Construct an addition problem. Precondition: Receives maxAddend, the largest integer to use in a problem Postcondition: An addition problem has been constructed with addends that are random integers in the range 0 through maxAddend and myTries initialized to 1. -----------------------------------------------------------*/ void display(ostream & out) const; /*----------------------------------------------------------- Display the addition problem. Precondition: ostream out is open. Postcondition: Problem has been been output to out. -----------------------------------------------------------*/ int answer() const; /*----------------------------------------------------------- Get answer to addition problem. Precondition: None Postcondition: Answer to this addition problem is retrieved. -----------------------------------------------------------*/ private: /***** Data Members *****/ int myAddend1, myAddend2, myAnswer; }; //--- Initialize random number generator void initialize(); //--- Output operator ostream & operator<<(ostream & out, const AdditionProblem & problem); #endif |
B AdditionProblem.cpp |
/*-- AdditionProblem.cpp ------------------------------------------- This file implements operations for AdditionProblem objects. --------------------------------------------------------------------*/ #include <cstdlib> #include <ctime> using namespace std; #include "AdditionProblem.h" //--- Definition of AdditionProblem constructor AdditionProblem::AdditionProblem(int maxAddend) { myAddend1 = rand() % (maxAddend + 1); myAddend2 = rand() % (maxAddend + 1); myAnswer = myAddend1 + myAddend2; } //--- Definition of display() void AdditionProblem::display(ostream & out) const /*----------------------------------------------------------- Display values stored in the stack Precondition: out is ostream to use for output Postcondition: Stack's contents, from top down, have been output to out. -----------------------------------------------------------*/ { out << myAddend1 << " + " << myAddend2 << " = ? "; } //--- Definition of answer() int AdditionProblem::answer() const { return (myAddend1 + myAddend2); } //--- Definition of output operator] ostream & operator<<(ostream & out, const AdditionProblem & problem) { problem.display(out); return out; } //--- Definition of initialize() void initialize() { long seed = long(time(0)); // seed for random number generator srand(seed); } |
C Drill and Practice Program |
/*--------------------------------------------------------------------- Drill-and-Practice Program that generates random drill-and-practice addition problems. Problems that are answered incorrectly are queued and asked again until all are answered correctly or maximum number of tries is reached. Input: Number of problems to generate, student's answers to problems Output: Messages, problems, correct answers, number of problems answered correctly Note: Program assumes that Queue.h contains a declaration of a class Queue like that described in Sections 7.2 and 7.3 whose elements are of type AdditionProblem. An alternative is to use the C++ standard queue class template by making the following changes: #include "Queue.h" --> #include <queue> Queue wrongQueue --> queue<AdditionProblem> wrongQueue enqueue --> push dequeue --> pop -------------------------------------------------------------------*/ #include <iostream> // cin, cout, >>, << using namespace std; #include "AdditionProblem.h" // AdditionProblem, initialize() #include "Queue.h" // A queue class for AdditionProblems int main() { int numProblems, // number of problems asked maxAddend; // maximum addend in a problem const int MAX_ROUNDS = 3; // maximum number of rounds in // which to try the problems initialize(); // initialize random number generator cout << "*** Let's practice our addition skills! *** \n\n" "How many problems would you like? "; cin >> numProblems; cout << "What's the largest addend you would like? "; cin >> maxAddend; // Generate numProblems problems and store them in a queue. Queue problemQueue; // queue of problems for (int i = 1; i <= numProblems; i++) { AdditionProblem problem(maxAddend); problemQueue.enqueue(problem); } // Conduct the practice rounds AdditionProblem problem; // next addition problem int userAnswer, // user's answer to a problem numberMissed; // number of problems missed for (int round = 1; round <= MAX_ROUNDS; round++) { // One round of problems numberMissed = 0; for (int count = 1; count <= numProblems; count++) { problem = problemQueue.front(); problemQueue.dequeue(); cout << problem; cin >> userAnswer; if (userAnswer == problem.answer()) cout << "Correct!\n\n"; else { cout << "Sorry -- Try again later\n\n"; problemQueue.enqueue(problem); numberMissed++; } } if (numberMissed == 0) { cout << "Congratulations! You correctly answered all the" " problems in Round #" << round << endl; break; } else { cout << "\nYou missed " << numberMissed << " problems in Round #" << round << ".\n"; if (round < MAX_ROUNDS) cout << "You may now try them again. Good luck!\n"; numProblems = numberMissed; } } // Wrapup if (numberMissed == 0) cout << "You have finished the quiz and have successfully.\n" "answered all the problems. Good job!" << endl; else { cout << "\nYou have reached the limit on the number of tries " "allowed.\nHere are the problems you missed:\n\n"; while (!problemQueue.empty()) { problem = problemQueue.front(); problemQueue.dequeue(); cout << problem << " Answer: " << problem.answer() << "\n\n"; } cout << "Perhaps it would be a good idea to practice some more.\n"; } return 0; } |
2A Queue.h Using Static Array |
/* Queue.h contains the declaration of class Queue. Basic operations: Constructor: Constructs an empty queue empty: Checks if a queue is empty enqueue: Modifies a queue by adding a value at the back front: Accesses the front queue value; leaves queue unchanged dequeue: Modifies a queue by removing the value at the front display: Displays the queue elements from front to back Class Invariant: 1. The queue elements (if any) are stored in consecutive positions in myArray, beginning at position myFront. 2. 0 <= myFront, myBack < QUEUE_CAPACITY 3. Queue's size < QUEUE_CAPACITY ----------------------------------------------------------------*/ #include <iostream> #ifndef QUEUE #define QUEUE const int QUEUE_CAPACITY = 128; template<class ItemType> class Queue { public: /***** Function Members *****/ /***** Constructor *****/ Queue(); /*---------------------------------------------------------- Construct a Queue object. Precondition: None. Postcondition: An empty Queue object has been constructed; myFront and myBack are initialized to -1 and myArray is an array with QUEUE_CAPACITY elements of type QueueElement. -----------------------------------------------------------*/ bool empty() const; /*----------------------------------------------------------- Check if queue is empty Precondition: None. Postcondition: True is returned if the queue is empty and false is returned otherwise. -----------------------------------------------------------*/ void enqueue(const ItemType & value); /*----------------------------------------------------------- Add a value to a queue Precondition: value is to be added to this queue. Postcondition: value is added at back of queue provided there is space; otherwise, a queue-full message is displayed and execution is terminated. -----------------------------------------------------------*/ void display(ostream & out) const; /*----------------------------------------------------------- Output the values stored in the queue Precondition: out is ostream to use for output Postcondition: Queue's contents, from top down, have been output to out. -----------------------------------------------------------*/ ItemType front() const; /*----------------------------------------------------------- Retrieve value at front of queue (if any) Precondition: Queue is nonempty Postcondition: Value at front of queue is returned, unless queue is empty; in that case, an error message is displayed and a "garbage value" is returned. ----------------------------------------------------------*/ void dequeue(); /*----------------------------------------------------------- Remove value at front of queue (if any) Precondition: Queue is nonempty Postcondition: Value at front of queue has been removed, unless queue is empty; in that case, an error message is displayed and execution is terminated. ----------------------------------------------------------*/ private: /***** Data Members *****/ ItemType myArray[QUEUE_CAPACITY]; int myFront, myBack, |
2B Queue.cpp |
/*-- Queue.cpp----------------------------------------------------------- This file implements Queue member functions. -------------------------------------------------------------------------*/ #include <iostream> using namespace std; #include "Queue.h" //--- Definition of Queue constructor |
3A LQueue.h Class Declaration |
/*-- LQueue.h ------------------------------------------------------------- This header file defines a Queue data type. Basic operations: constructor: Constructs an empty queue empty: Checks if a queue is empty enqueue: Modifies a queue by adding a value at the back front: Accesses the top queue value; leaves queue unchanged dequeue: Modifies queue by removing the value at the front display: Displays all the queue elements -------------------------------------------------------------------------*/ #include <iostream> #ifndef LQUEUE #define LQUEUE template<class ItemType> class Queue { public: /***** Function Members *****/ /***** Constructors *****/ Queue(); /*----------------------------------------------------------------------- Construct a Queue object. Precondition: None. Postcondition: An empty Queue object has been constructed. (myFront and myBack are initialized to null pointers). -----------------------------------------------------------------------*/ Queue(const Queue & original); /*----------------------------------------------------------------------- Copy Constructor Precondition: original is the queue to be copied and is received as a const reference parameter. Postcondition: A copy of original has been constructed. -----------------------------------------------------------------------*/ /***** Destructor *****/ ~Queue(); /*----------------------------------------------------------------------- Class destructor Precondition: None. Postcondition: The linked list in the queue has been deallocated. -----------------------------------------------------------------------*/ /***** Assignment *****/ const Queue & operator= (const Queue & rightHandSide); /*----------------------------------------------------------------------- Assignment Operator Precondition: rightHandSide is the queue to be assigned and is received as a const reference parameter. Postcondition: The current queue becomes a copy of rightHandSide and a reference to it is returned. -----------------------------------------------------------------------*/ bool empty() const; /*----------------------------------------------------------------------- Check if queue is empty. Precondition: None. Postcondition: Returns true if queue is empty and false otherwise. -----------------------------------------------------------------------*/ void enqueue(const ItemType & value); /*----------------------------------------------------------------------- Add a value to a queue. Precondition: value is to be added to this queue. Postcondition: value is added at back of queue. -----------------------------------------------------------------------*/ void display(ostream & out) const; /*----------------------------------------------------------------------- Display values stored in the queue. Precondition: ostream out is open. Postcondition: Queue's contents, from front to back, have been output to out. -----------------------------------------------------------------------*/ ItemType front() const; /*----------------------------------------------------------------------- Retrieve value at front of queue (if any). Precondition: Queue is nonempty. Postcondition: Value at front of queue is returned, unless the queue is empty; in that case, an error message is displayed and a "garbage value" is returned. -----------------------------------------------------------------------*/ void dequeue(); /*----------------------------------------------------------------------- Remove value at front of queue (if any). Precondition: Queue is nonempty. Postcondition: Value at front of queue has been removed, unless queue is empty; in that case, an error message is displayed and execution allowed to proceed. -----------------------------------------------------------------------*/ private: /*** Node class ***/ class Node { public: ItemType data; Node * next; //--- Node constructor Node(ItemType value, Node * link = 0) /*------------------------------------------------------------------- Precondition: value and link are received Postcondition: A Node has been constructed with value in its data part and its next part set to link (default 0). ------------------------------------------------------------------*/ { data = value; next = link; } }; typedef Node * NodePointer; /***** Data Members *****/ NodePointer myFront, // pointer to front of queue myBack; // pointer to back of queue }; // end of class declaration #endif |
3B LQueue.cpp, Implementation |
/*--- LQueue.cpp ---------------------------------------------------------- This file implements LQueue member functions. -------------------------------------------------------------------------*/ #include <new> using namespace std; #include "LQueue.h" //--- Definition of Queue constructor |
3C Driver Program to Test Queue Class |
/*--------------------------------------------------------------------- Driver program to test the Queue class. ----------------------------------------------------------------------*/ #include <iostream> using namespace std; #include "LQueue.h" void print(Queue q) { q.display(cout); } int main() { Queue q1; cout << "Queue created. Empty? " << boolalpha << q1.empty() << endl; cout << "How many elements to add to the queue? "; int numItems; cin >> numItems; for (int i = 1; i <= numItems; i++) q1.enqueue(100*i); cout << "Contents of queue q1 (via print):\n"; print(q1); cout << endl; Queue q2; q2 = q1; cout << "Contents of queue q2 after q2 = q1 (via print):\n"; print(q2); cout << endl; cout << "Queue q2 empty? " << q2.empty() << endl; cout << "Front value in q2: " << q2.front() << endl; while (!q2.empty()) { cout << "Remove front -- Queue contents: "; q2.dequeue(); q2.display(cout); } cout << "Queue q2 empty? " << q2.empty() << endl; cout << "Front value in q2?" << endl << q2.front() << endl; cout << "Trying to remove front of q2: " << endl; q2.dequeue(); } |
4 Simulation Class -- Data Members |
/*-- Simulation.h ---------------------------------------------------------- Header file to define a Simulation data type for simulating the operation of an information/reservation center that services telephone calls. Basic operations: constructor: constructs a Simulation object run(): carry out the simulation display(): output results of the simulation service(): service an incoming call checkForNewCall(): check if a new call has come in Note: Assumes availability of a queue class with elements of type Call. -------------------------------------------------------------------------*/ #include <iostream> // istream, ostream, >>, << #include <ctime> // time() #ifndef SIMULATION #define SIMULATION #include "Timer.h" #include "Call.h" #include "LQueue.h" // Queue with elements of type Call const int NUM_CATEGORIES = 5; class Simulation { public: /***** Function Members *****/ /***** Constructor *****/ Simulation(); /*----------------------------------------------------------------------- Construct a Simulation object. Precondition: None Postcondition: Input data members have been initialized with values entered by the user; output data members have been initialized to 0; and random number generator has been initialized. -----------------------------------------------------------------------*/ /***** Running the simulation *****/ void run(); /*----------------------------------------------------------------------- Run the simulation. Precondition: None. Postcondition: Simulation of phone service has been completed and performance statistics output. -----------------------------------------------------------------------*/ /***** Output *****/ void display(ostream & out); /*---------------------------------------------------------------------- Display results of the simulation. Precondition: ostream out is open. Postcondition: Total number of calls and the average waiting time for calls have been output to out. -----------------------------------------------------------------------*/ /***** Call processing *****/ void service(int & busyTimeRemaining); /*---------------------------------------------------------------------- Service the current call (if any). Precondition: None Postcondition: busyTimeRemaining has been decremented by one if a call was being serviced; otherwise, if there were incoming calls, a call has been removed from myIncomingCalls, its service time assigned to busyTimeRemaining, and its waiting time in the queue added to myTotalWaitingTime. -----------------------------------------------------------------------*/ void checkForNewCall(); /*---------------------------------------------------------------------- Check if a new call has arrived and if so, add it to the queue of incoming calls. Precondition: None. Postcondition: myIncomingCalls has been updated. -----------------------------------------------------------------------*/ private: /***** Data Members *****/ //-- Inputs int myLengthOfSimulation; double myArrivalRate; int myServicePercent[NUM_CATEGORIES]; //-- Outputs int myCallsReceived; double myTotalWaitingTime; //-- Countdown Timer Timer myTimer; //-- Queue of calls waiting for service Queue myIncomingCalls; }; // end of class declaration #endif |
5 Simulation Class -- Function Members |
/*-- Simulation.cpp -------------------------------------------------------- Definitions of function members of class Simulation. -------------------------------------------------------------------------*/ #include <iostream> // istream, ostream, >>, << #include <cstdlib> // rand(), srand() #include <ctime> // time() using namespace std; #include "Simulation.h" //--- Definition of constructor Simulation::Simulation() { //-- Initialize output statistics myCallsReceived = 0; myTotalWaitingTime = 0; //-- Get simulation parameters cout << "Enter arrival rate (calls per hour): "; int callsPerHour; cin >> callsPerHour; myArrivalRate = callsPerHour / 60.0; // convert to calls per minute cout << "Enter percent of calls serviced in\n"; int percent, sum = 0; for (int i = 0; i < NUM_CATEGORIES - 1; i++) { cout << " <= " << i + 1 << " min. "; cin >> percent; sum += percent; myServicePercent[i] = sum; } myServicePercent[NUM_CATEGORIES - 1] = 100; cout << "Enter # of minutes to run simulation: "; cin >> myLengthOfSimulation; // Set the countdown timer myTimer.set(myLengthOfSimulation); //-- Initialize random number generator long seed = long(time(0)); // seed for random number generator srand(seed); } //--- Definition of run() void Simulation::run() { // Begin the simulation int busyTimeLeft = 0; while (myTimer.timeRemaining() > 0) { service(busyTimeLeft); checkForNewCall(); myTimer.tick(); } cout << "\nNot accepting more calls -- service those waiting\n"; // Service any remaining calls in incomingCalls queue while (!myIncomingCalls.empty()) { service(busyTimeLeft); myTimer.tick(); } // Output the results display(cout); } //--- Definition of display() void Simulation::display(ostream & out) { out << "\nNumber of calls processed: " << myCallsReceived << "\nAve. waiting time per call: " << myTotalWaitingTime / myCallsReceived << " minutes" << endl; } //--- Definition of service() void Simulation::service(int & busyTimeRemaining) { if (busyTimeRemaining > 0) // servicing a call busyTimeRemaining--; // service it for another minute else if (!myIncomingCalls.empty()) // calls are waiting -- get one { Call nextCall = myIncomingCalls.front(); myIncomingCalls.dequeue(); busyTimeRemaining = nextCall.getServiceTime(); // Update total waiting time myTotalWaitingTime += nextCall.getArrivalTime() - myTimer.timeRemaining(); } } //--- Definition of checkForNewCall() void Simulation::checkForNewCall() { int x = rand() % 100; if (x < 100 * myArrivalRate) { // A new call has arrived. Generate a random service time for it int r = rand() % 100; int serviceTime = 0; while (r > myServicePercent[serviceTime]) serviceTime++; // Construct a new call and add it to queue of incoming calls Call newCall(myTimer, serviceTime + 1); myIncomingCalls.enqueue(newCall); myCallsReceived++; } } |
5B Driver Program for Simulation |
/*------------------------------------------------------------- Driver program for simulation of information/reservation center that services telephone calls --------------------------------------------------------------*/ using namespace std; #include "Simulation.h" int main() { Simulation sim; sim.run(); return 0; } |
Figure Timer Class .h and .cpp |
/*-- Timer.h --------------------------------------------------- This header file defines a class Timer that models a countdown timer. Basic operations: constructor: constructs a Timer object set(): mutator to set/reset the timer tick(): decrease timer by 1 time unit (minute) hasTimeLeft(): checks if any time remains timeRemaining(): determines how much time remains --------------------------------------------------------------*/ #ifndef TIMER #define TIMER class Timer { public: /***** Function Members *****/ /***** Constructor *****/ Timer (int initTime = 0); /*---------------------------------------------------------- Construct a Timer object. Precondition: The initial value initTime to start the timer is received. Postcondition: myMinutes has been initialized to initTime minutes (default 0). -----------------------------------------------------------*/ /***** Set timer *****/ void set(int minutes); /*---------------------------------------------------------- Set/reset the timer. Precondition: None Postcondition: myMinutes has been set to minutes. -----------------------------------------------------------*/ /***** Decrement timer *****/ void tick(); /*---------------------------------------------------------- Advance the clock one minute. Precondition: None Postcondition: myMinutes has been decremented by 1. -----------------------------------------------------------*/ /***** Check time remaining *****/ int timeRemaining() const; /*---------------------------------------------------------- Find how much time remains on the countdown timer. Precondition: None Postcondition: Time left before timer runs out is returned. -----------------------------------------------------------*/ private: /***** Data Members *****/ int myMinutes; }; // end of class declaration #endif /*-- Timer.cpp ------------------------------------------------- Contains definitions of function members of class Timer --------------------------------------------------------------*/ #include <cassert> using namespace std; #include "Timer.h" //--- Definition of constructor Timer::Timer(int initTime) { assert(initTime >= 0); myMinutes = initTime; } //--- Definition of set() void Timer::set(int minutes) { assert(minutes >= 0); myMinutes = minutes; } //--- Definition of tick() void Timer::tick() { myMinutes--; } //--- Definition of timeRemaining() int Timer::timeRemaining() const { return myMinutes; } |
Figure Call Class .h and .cpp Files |
/*-- Call.h --------------------------------------------------- This header file defines a class Call that models phone calls. Basic operations: constructors: construct a Call object getArrivalTime(): accessor to get time call arrived getServiceTime(): get time needed to service the call display(): display information about the call <<: output operator for a Call object --------------------------------------------------------------*/ #include <iostream> #include "Timer.h" #ifndef CALL #define CALL class Call { public: /***** Function Members *****/ /***** Constructor *****/ Call(); /*---------------------------------------------------------- Construct a Call object (default). Precondition: None Postcondition: All data members are initialized to 0. -----------------------------------------------------------*/ Call(const Timer & t, int serviceTime); /*---------------------------------------------------------- Construct a Call object (explicit-value). Precondition: Countdown timer t is received Postcondition: myTimeOfArrival has been set to time left on Timer t and myServiceTime to serviceTime. -----------------------------------------------------------*/ int getArrivalTime() const; /*---------------------------------------------------------- Accessor function for arrival time. Precondition: None Postcondition: Value of myTimeOfArrival was returned. -----------------------------------------------------------*/ int getServiceTime() const; /*---------------------------------------------------------- Accessor function for service time. Precondition: None Postcondition: Value of myServiceTime was returned. -----------------------------------------------------------*/ void display(ostream & out) const; /*---------------------------------------------------------- Display call Precondition: ostream out is a reference parameter Postcondition: Call has been output to out. -----------------------------------------------------------*/ private: /***** Data Members *****/ int myTimeOfArrival; int myServiceTime; }; // end of Timer class declaration //--- Prototype for output operator ostream & operator<<(ostream & out, const Call & aCall); #endif /*-- Call.cpp -------------------------------------------------- Contains definitions of the basic Call operations. --------------------------------------------------------------*/ #include <iostream> #include <cassert> using namespace std; #include "Call.h" //--- Definition of Default Constructor Call::Call() { myTimeOfArrival = myServiceTime = 0; } //--- Definition of Explicit-Value Constructor Call::Call(const Timer & t, int serviceTime) { // record call's time of arrival myTimeOfArrival = t.timeRemaining(); // set its service time myServiceTime = serviceTime; } //--- Definition of getArrivalTime() int Call::getArrivalTime() const { return myTimeOfArrival; } //--- Definition of getServiceTime() int Call::getServiceTime() const { return myServiceTime; } //--- Definition of display() void Call::display(ostream & out) const { out << "Arrival Time: " << myTimeOfArrival << endl << "Service Time: " << myServiceTime << endl; } //-- Definition of output operator ostream & operator<<(ostream & out, const Call & aCall) { aCall.display(out); return out; } |