0% found this document useful (0 votes)
198 views48 pages

12

The document provides an implementation of a Cow class with member functions to initialize, copy, assign, and display Cow objects. It includes the class definition in cow.h and implementation in cow.cpp. A test program is also provided that uses all the member functions to create and manipulate Cow objects.

Uploaded by

hpss77
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
198 views48 pages

12

The document provides an implementation of a Cow class with member functions to initialize, copy, assign, and display Cow objects. It includes the class definition in cow.h and implementation in cow.cpp. A test program is also provided that uses all the member functions to create and manipulate Cow objects.

Uploaded by

hpss77
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 48

1.

Consider the following class declaration:


class Cow {
char name[20];
char * hobby;
double weight;
public:
Cow();
Cow(const char * nm, const char * ho, double wt);
Cow(const Cow c&);
~Cow();
Cow & operator=(const Cow & c);
void ShowCow() const; // display all cow data
};
Provide the implementation for this class and write a short program that uses all the
member functions.
My answer:
cow.h
1

#ifndef COW_H_

#define COW_H_

3
4

class Cow

private:

char name[20];

char * hobby;

double weight;

10 public:
11

Cow();

12

Cow(const char * nm, const char * ho, double wt);

13

Cow(const Cow & c);

14

~Cow();

15

Cow & operator=(const Cow & c);

16

void ShowCow() const; // display all cow data

17 };
18
19 #endif
cow.cpp
1

#include <iostream>

#include "cow.h"

3
4

Cow::Cow()

name[0] = '\0';

hobby = NULL;

weight = 0;

10
11 Cow::Cow (const char * nm, const char * ho, double wt)
12 {
13

strcpy(name,nm);

14

hobby = new char [strlen(ho)+1];

15

strcpy(hobby,ho);

16

weight = wt;

17 }

18
19 Cow::Cow (const Cow & c)
20 {
21

strcpy(name,c.name);

22

hobby = new char [strlen(c.hobby)+1];

23

strcpy(hobby,c.hobby);

24

weight = c.weight;

25 }
26
27 Cow::~Cow()
28 {
29

delete [] hobby;

30 }
31
32 Cow & Cow::operator=(const Cow & c)
33 {
34

if (this == &c) // object assigned to itself

35

return *this;

36

delete [] hobby;

37

strcpy(name,c.name);

38

hobby = new char[strlen(c.hobby)+1];

39

strcpy(hobby,c.hobby);

40

weight = c.weight;

41

return *this;

42 }
43
44 void Cow::ShowCow() const
45 {
46

std::cout << "\nName: " << name;

47

if (hobby == NULL)

48

std::cout << "\nHobby: [empty - please initialize]";

49

else

50

std::cout << "\nHobby: " << hobby;

51

std::cout << "\nWeight: " << weight << std::endl;

52 }
cp12ex1.cpp
1

#include <iostream>

#include "cow.h"

3
4

int main()

using namespace std;

7
8

Cow name1("Big Fat Cow","Eating grass",300.5);

Cow name2;

10

Cow name3 = name1; // copy constructor is used

11

12

name1.ShowCow();

13

name2.ShowCow();

14

name3.ShowCow();

15
16

Cow name4("Small Cow","running around",150);

17

name2 = name4; // assignment

18

name2.ShowCow();

19
20

Cow name5("Average Cow","sleeping",200);

21
22

name1 = name2 = name3 = name4 = name5;

23
24

name1.ShowCow();

25

name2.ShowCow();

26

name3.ShowCow();

27
28

cin.get();

29

cin.get();

30

return 0;

31 }
Fran says:
August 22, 2012 at 10:35 am
Cow & Cow::operator=(const Cow & c)
{
if (this == &c) // object assigned to itself
return *this;
delete [] hobby;
strcpy(name,c.name);

hobby = new char[strlen(c.hobby)+1];


strcpy(hobby,c.hobby);
weight = c.weight;
return *this;
}
With this youre not deleting the initially memory allocated by new when the object was
constructed. You should create a temporary char*, assign the address of hobby to it, allocate
new memory in the heap with hobby, and delete the initial memory with delete[] temp.

2. Enhance the String class declaration (that is, upgrade string1.h to string2.h) by
doing the following:
a. Overload the + operator to allow you to join two strings into one.
b. Provide a stringlow() member function that converts all alphabetic characters in
a string to lowercase. (Dont forget the cctype family of character functions.)
c. Provide a stringup() member function that converts all alphabetic characters in a
string to uppercase.
d. Provide a member function that takes a char argument and returns the number of
times the character appears in the string.
test your work in the following program:
// pe12_2.cpp
#include
using namespace std;
#include string2.h
int main()
{
String s1( and I am a C++ student.);
String s2 = Please enter your name: ;
String s3;
cout << s2; // overloaded << operator
cin >> s3; // overloaded >> operator
s2 = My name is + s3; // overloaded =, + operators
cout << s2 << .\n;
s2 = s2 + s1;
s2.stringup(); // converts string to uppercase
cout << The string\n << s2 << \ncontains << s2.has(A)
<< A characters in it.\n;
s1 = red; // String(const char *),
// then String & operator=(const String&)
String rgb[3] = { String(s1), String(green), String(blue)};
cout << Enter the name of a primary color for mixing light: ;
String ans;
bool success = false;
while (cin >> ans)
{
ans.stringlow(); // converts string to lowercase
for (int i = 0; i < 3; i++)
{

if (ans == rgb[i]) // overloaded == operator


{
cout << Thats right!\n;
success = true;
break;
}
}
if (success)
break;
else
cout << Try again!\n;
}
cout << Bye\n;
return 0;
}
Your output should look like this sample run:
Please enter your name: Fretta Farbo
My name is Fretta Farbo.
The string
MY NAME IS FRETTA FARBO AND I AM A C++ STUDENT.
contains 6 A characters in it.
Enter the name of a primary color for mixing light: yellow
Try again!
BLUE
Thats right!
Bye
My answer:
string2.h
1 #include <iostream>
2 using std::ostream;
3 using std::istream;
4 #ifndef STRING2_H_
5 #define STRING2_H_
6 class String
7 {
8 private:
9

char * str; // pointer to string

10

int len; // length of string

11

static int num_strings; // number of objects

12

static const int CINLIM = 80; // cin input limit

13 public:
14

// constructors and other methods

15

String(const char * s); // constructor

16

String(); // default constructor

17

String(const String &); // copy constructor

18

~String(); // destructor

19

int length () const { return len; }

20

void stringlow();

21

void stringup();

22

int has(char ch) const;

23

// overloaded operator methods

24

String & operator=(const String &);

25

String & operator=(const char *);

26

String operator+(const String & st);

27

friend String operator+(const char *, const String & st);

28

char & operator[](int i);

29

const char & operator[](int i) const;

30

// overloaded operator friends

31

friend bool operator<(const String &st, const String &st2);

32

friend bool operator>(const String &st1, const String &st2);

33

friend bool operator==(const String &st, const String &st2);

34

friend ostream & operator<<(ostream & os, const String & st);

35

friend istream & operator>>(istream & is, String & st);

36

// static function

37

static int HowMany();

38 };
39 #endif
string2.cpp
1

#include <cstring> // string.h for some

#include "string2.h" // includes <iostream>

#include <cctype>

using std::cin;

using std::cout;

// initializing static class member

int String::num_strings = 0;

// static method

int String::HowMany()

10

11

return num_strings;

12

13

// class methods

14

String::String(const char * s) // construct String from C string

15

16

len = std::strlen(s); // set size

17

str = new char[len + 1]; // allot storage

18

std::strcpy(str, s); // initialize pointer

19

num_strings++; // set object count

20

21

String::String() // default constructor

22

23

len = 4;

24

str = new char[1];

25

str[0] = '\0'; // default string

26

num_strings++;

27

28

String::String(const String & st)

29

30

num_strings++; // handle static member update

31

len = st.len; // same length

32

str = new char [len + 1]; // allot space

33

std::strcpy(str, st.str); // copy string to new location

34

35

String::~String() // necessary destructor

36

37

--num_strings; // required

38

delete [] str; // required

39
40

41

void String::stringlow()

42

43

char * temp = new char[len+1];

44

strcpy(temp,str);

45
46

for (int i = 0; i < len; i++)

47

temp[i] = tolower(temp[i]);

48

strcpy(str,temp);

49

delete [] temp;

50
51

52
53

void String::stringup()

54

55

char * temp = new char[len+1];

56

strcpy(temp,str);

57
58

for (int i = 0; i < len; i++)

59

temp[i] = toupper(temp[i]);

60

strcpy(str,temp);

61

delete [] temp;

62
63
64

65

int String::has (char ch) const

66

67

int chnum = 0;

68

for (int i=0; i < len; i++)

69

70

if (str[i] == ch)

71

chnum++;

72

73
74

return chnum;

75
76

77
78

// overloaded operator methods

79

// assign a String to a String

80
81

String String::operator+(const String & st)

82

83

String temp;

84

temp.len = len + st.len + 1;

85

temp.str = new char [temp.len];

86

strcpy(temp.str,str);

87

strcat(temp.str,st.str);

88

89
90

return temp;
}

91
92

String operator+(const char * st2, const String & st)

93

94

String temp;

95

temp.len = st.len + strlen(st2) + 1;

96

temp.str = new char [temp.len];

97

strcpy(temp.str,st2);

98

strcat(temp.str,st.str);

99
100

return temp;

101 }
102 String & String::operator=(const String & st)
103 {
104

if (this == &st)

105

return *this;

106

delete [] str;

107

len = st.len;

108

str = new char[len + 1];

109

std::strcpy(str, st.str);

110

return *this;

111 }
112 // assign a C string to a String

113 String & String::operator=(const char * s)


114 {
115

delete [] str;

116

len = std::strlen(s);

117

str = new char[len + 1];

118

std::strcpy(str, s);

119

return *this;

120 }
121 // read-write char access for non-const String
122 char & String::operator[](int i)
123 {
124

return str[i];

125 }
126 // read-only char access for const String
127 const char & String::operator[](int i) const
128 {
129

return str[i];

130 }
131 // overloaded operator friends
132 bool operator<(const String &st1, const String &st2)
133 {
134

return (std::strcmp(st1.str, st2.str) < 0);

135 }
136 bool operator>(const String &st1, const String &st2)

137 {
138

return st2.str < st1.str;

139 }
140 bool operator==(const String &st1, const String &st2)
141 {
142

return (std::strcmp(st1.str, st2.str) == 0);

143 }
144 // simple String output
145 ostream & operator<<(ostream & os, const String & st)
146 {
147

os << st.str;

148

return os;

149 }
150 // quick and dirty String input
151 istream & operator>>(istream & is, String & st)
152 {
153

char temp[String::CINLIM];

154

is.get(temp, String::CINLIM);

155

if (is)

156
157
158
159
160 }

st = temp;
while (is && is.get() != '\n')
continue;
return is;

cp12ex2.cpp
1 #include <iostream>
2 using namespace std;
3 #include "string2.h"
4 int main()
5 {
6

String s1(" and I am a C++ student.");

String s2 = "Please enter your name: ";

8
9

String s3;

10

cout << s2; // overloaded << operator

11

cin >> s3; // overloaded >> operator

12

s2 = "My name is " + s3; // overloaded =, + operators

13

cout << s2 << ".\n";

14

s2 = s2 + s1;

15

s2.stringup(); // converts string to uppercase

16

cout << "The string\n" << s2 << "\ncontains " << s2.has('A') << " 'A' characters in it.\n";

17

s1 = "red"; // String(const char *),

18

// then String & operator=(const String&)

19

String rgb[3] = {String(s1), String("green"), String("blue")};

20

cout << "Enter the name of a primary color for mixing light: ";

21

String ans;

22

bool success = false;

23

while (cin >> ans)

24

25

ans.stringlow(); // converts string to lowercase

26

for (int i = 0; i < 3; i++)

27

28

if (ans == rgb[i]) // overloaded == operator

29

30

cout << "That's right!\n";

31

success = true;

32

break;

33

34

35

if (success)

36

break;

37

else

38
39

cout << "Try again!\n";


}

40
41

cout << "Bye\n";

42

cin.get();

43

cin.get();

44

return 0;

45}
Saad says:
April 7, 2012 at 6:50 pm

The operator+ overloaded functions return objects that cease to exist upon termination of the
function, returned data will be garbled as the memory they point to has been cleared by the
destructor. Another solution is required.
Reply

Saad says:
April 7, 2012 at 7:02 pm
My bad it works, I was using a & operator+ overload in my implementation :P
Reply

Saad says:
April 7, 2012 at 7:06 pm
String String::operator+(const String & st)
{
String tmp;
tmp.len = len + st.len;
delete [] tmp.str; //Default constructor allocates enough room for null char, must clear that.
tmp.str = new char[tmp.len+1];
strcpy(tmp.str, str);
strcat(tmp.str, st.str);
return tmp;
}
String operator+(const char *st1, const String &st2)
{
String tmp;
tmp.len = strlen(st1) + st2.len + 1;
delete [] tmp.str; //Clear default constructor allocated memory.
tmp.str = new char[tmp.len];
strcpy(tmp.str, st1);
strcat(tmp.str, st2.str);
return tmp;
}
Reply

Fran says:
August 22, 2012 at 11:49 am
You define to operator+ functions, one as a method and the other as a friend. But this is
unnecessary becuase the friend function already deals with all posible combinations.

Reply

Fran says:
August 22, 2012 at 11:51 am
OTOH, why do you create a temporary char* in the stringlow() and stringup()
methods? You can deal directly with str without the need of dynamic memory
allocation.

Saad says:
April 7, 2012 at 6:50 pm
The operator+ overloaded functions return objects that cease to exist upon termination of the
function, returned data will be garbled as the memory they point to has been cleared by the
destructor. Another solution is required.
Reply

Saad says:
April 7, 2012 at 7:02 pm
My bad it works, I was using a & operator+ overload in my implementation :P
Reply

Saad says:
April 7, 2012 at 7:06 pm
String String::operator+(const String & st)
{
String tmp;
tmp.len = len + st.len;
delete [] tmp.str; //Default constructor allocates enough room for null char, must clear that.
tmp.str = new char[tmp.len+1];
strcpy(tmp.str, str);
strcat(tmp.str, st.str);
return tmp;
}
String operator+(const char *st1, const String &st2)
{
String tmp;
tmp.len = strlen(st1) + st2.len + 1;
delete [] tmp.str; //Clear default constructor allocated memory.
tmp.str = new char[tmp.len];

strcpy(tmp.str, st1);
strcat(tmp.str, st2.str);
return tmp;
}
Reply

Fran says:
August 22, 2012 at 11:49 am
You define to operator+ functions, one as a method and the other as a friend. But this is
unnecessary becuase the friend function already deals with all posible combinations.
Reply

Fran says:
August 22, 2012 at 11:51 am
OTOH, why do you create a temporary char* in the stringlow() and stringup()
methods? You can deal directly with str without the need of dynamic memory
allocation.

++++++++
3. Rewrite the Stock class, as described in Listings 10.7 and 10.8 in Chapter 10,
so that it
uses dynamically allocated memory directly instead of using string class objects
to hold
the stock names. Also, replace the show() member function with an overloaded
operator<<() definition. Test the new definition program in Listing 10.9.
stock2.h
1 #ifndef STOCK2_H_
2 #define STOCK2_H_
3 class Stock
4 {
5 private:
6

char * company;

int shares;

double share_val;

double total_val;

10

void set_tot() { total_val = shares * share_val; }

11 public:
12

Stock(); // default constructor

13

Stock(const char * co, int n = 0, double pr = 0.0);

14

Stock(const Stock & st);

15

Stock & operator=(const Stock &);

16

~Stock();

17

void buy(int num, double price);

18

void sell(int num, double price);

19

void update(double price);

20

const Stock & topval(const Stock & s) const;

21

friend std::ostream & operator<<(std::ostream & os, const Stock & s);

22 };
23 #endif
stock2.cpp
1

#include <iostream>

#include "stock2.h"

// constructors

Stock::Stock() // default constructor

//std::strcpy(company, "no name");

company = new char [strlen("no name")+1];

std::strcpy(company,"no name");

shares = 0;

10

share_val = 0.0;

11

total_val = 0.0;

12 }
13 Stock::Stock(const char * co, int n, double pr)
14 {
15

company = new char[strlen(co)+1];

16

std::strcpy(company,co);

17

if (n < 0)

18

19

std::cerr << "Number of shares can't be negative; "

20

<< company << " shares set to 0.\n";

21

shares = 0;

22

23

else

24

shares = n;

25
26

share_val = pr;

27

set_tot();

28 }
29
30 // copy constructor
31 Stock::Stock(const Stock &st)
32 {
33

company = new char[strlen(st.company)+1];

34

std::strcpy(company,st.company);

35

shares = st.shares;

36

share_val = st.share_val;

37

total_val = st.total_val;

38

set_tot();

39 }
40
41 // assignment constructor
42 Stock & Stock::operator=(const Stock & st)
43 {
44

if (this == &st)

45

return *this;

46

delete [] company;

47

company = new char[strlen(st.company)+1];

48

std::strcpy(company,st.company);

49

shares = st.shares;

50

share_val = st.share_val;

51

total_val = st.total_val;

52

set_tot();

53

return *this;

54 }
55
56 // class destructor
57 Stock::~Stock() // quiet class destructor
58 {
59

delete [] company;

60 }
61 // other methods
62 void Stock::buy(int num, double price)
63 {
64

if (num < 0)

65

66

std::cerr << "Number of shares purchased can't be negative. "

67

<< "Transaction is aborted.\n";

68

69

else

70

71

shares += num;

72

share_val = price;

73

set_tot();

74

75 }
76 void Stock::sell(int num, double price)
77 {
78

using std::cerr;

79

if (num < 0)

80

81

cerr << "Number of shares sold can't be negative. "

82

<< "Transaction is aborted.\n";

83

84

else if (num > shares)

85

86

cerr << "You can't sell more than you have! "

87

<< "Transaction is aborted.\n";

88

89

else

90

91

shares -= num;

92

share_val = price;

93

set_tot();

94

95 }
96 void Stock::update(double price)
97 {
98

share_val = price;

99

set_tot();

100 }
101
102 const Stock & Stock::topval(const Stock & s) const
103 {
104
105
106
107

if (s.total_val > total_val)


return s;
else
return *this;

108 }
109
110 std::ostream & operator<<(std::ostream & os, const Stock & s)
111 {
112

os << "Company: " << s.company

113

<< " Shares: " << s.shares << std::endl

114

<< " Share Price: $" << s.share_val

115

<< " Total Worth: $" << s.total_val << std::endl;

116

return os;

117 }
cp12ex3.cpp
1 #include <iostream>
2 #include "stock2.h"
3 const int STKS = 4;
4 int main()
5{
6

using std::cout;

using std::ios_base;

8 // create an array of initialized objects


9

Stock stocks[STKS] = { // copy constructor

1
0

Stock("NanoSmart", 12, 20.0),

1
1
1
2

Stock("Boffo Objects", 200, 2.0),


Stock("Monolithic Obelisks", 130, 3.25),
Stock("Fleep Enterprises", 60, 6.5)};

1
3

cout.precision(2); // #.## format

1
4

cout.setf(ios_base::showpoint); // #.## format

cout.setf(ios_base::fixed, ios_base::floatfield);// #.## format

1
5

cout << "Stock holdings:\n";

1
6

for (st = 0; st < STKS; st++)

1
7

Stock top = stocks[0]; // copy constructor

1
8
1
9
2

int st;

cout << stocks[st];

for (st = 1; st < STKS; st++)


top = top.topval(stocks[st]); // assignment constructor
cout << "\nMost valuable holding:\n";
cout << top;

std::cin.get();
0

std::cin.get();

2
1

return 0;

2}
2

Just curious, why did you write a copy constructor you have double calls to std::cin.get()

2 in most of your code.. Maybe I forgot, but whats that about?


3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1

Reply

Fran says:
August 22, 2012 at 12:54 pm
Thats because when you manage memory dynamically with classes you need to
use one of those to do deep copying and not simply copying the same address from
one object to another. (in this specific program I think its not necessary, neither is
necessary the overloaded assignment operator but just for precaucion, its a good
practice) The cin.get() its because in windows console applications, when the
program finishes it automatically closes the window, you cannot see anything at all.
This way the window remains open until the user press any key and the program
terminates (he really needed only one cin.get() in this case, the two are redundant).
BTW, he has one error in cout << top. As top is a Stock *, it will display its address,
it won't call operator<<(). For it to call the function he needs to put cout << *top, as
it's expecting an object, not a pointer.

+++++++++++

4. Consider the following variation of the Stack class defined in Listing 10.10:
// stack.h class declaration for the stack ADT
typedef unsigned long Item;
class Stack
{
private:
enum {MAX = 10}; // constant specific to class
Item * pitems; // holds stack items
int size; // number of elements in stack
int top; // index for top stack item
public:
Stack(int n = 10); // creates stack with n elements
Stack(const Stack & st);
~Stack();

bool isempty() const;


bool isfull() const;
// push() returns false if stack already is full, true otherwise
bool push(const Item & item); // add item to stack
// pop() returns false if stack already is empty, true otherwise
bool pop(Item & item); // pop top into item
Stack & operator=(const Stack & st);
};
As the private members suggest, this class uses a dynamically allocated array to
hold the
stack items. Rewrite the methods to fit this new representation and write a
program that
demonstrates all the methods, including the copy constructor and assignment
operator.
d_stack.h
1 #ifndef D_STACK_H_
2 #define D_STACK_H_
3
4 typedef unsigned long Item;
5
6 class Stack
7 {
8 private:
9

enum {MAX = 10}; // constant specific to class

10

Item * pitems; // holds stack items

11

int size; // number of elements in stack

12

int top; // index for top stack item

13 public:
14

Stack(int n = MAX); // creates stack with n elements

15

Stack(const Stack & st);

16

~Stack();

17

bool isempty() const;

18

bool isfull() const;

19

// push() returns false if stack already is full, true otherwise

20

bool push(const Item & item); // add item to stack

21

// pop() returns false if stack already is empty, true otherwise

22

bool pop(Item & item); // pop top into item

23

Stack & operator=(const Stack & st);

24 };
25
26 #endif
d_stack.cpp
1

#include "d_stack.h"

Stack::Stack(int n) // create an empty stack

size = n;

pitems = new Item [n];

top = 0;

8
9

Stack::Stack(const Stack & st)

10 {
11

size = st.size;

12

top = st.top;

13

pitems = new Item [size];

14

for (int i = 0; i < size; i++)

15

pitems[i] = st.pitems[i];

16 }
17
18 bool Stack::isempty() const
19 {
20

return top == 0;

21 }
22 bool Stack::isfull() const
23 {
24

return top == size;

25 }
26 bool Stack::push(const Item & item)

27 {
28

if (top < size)

29

30

pitems[top++] = item;

31

return true;

32

33

else

34

return false;

35 }
36 bool Stack::pop(Item & item)
37 {
38

if (top > 0)

39

40

item = pitems[--top];

41

return true;

42

43

else

44

return false;

45 }
46
47 Stack::~Stack()
48 {
49

delete [] pitems;

50 }
51
52 Stack & Stack::operator=(const Stack & st)
53 {
54

if (this == &st)

55

return *this;

56

delete [] pitems;

57

size = st.size;

58

top = st.top;

59

pitems = new Item [size];

60

for (int i = 0; i < size; i++)

61

pitems[i] = st.pitems[i];

62

return *this;

63 }
cp12ex4.cpp
1 #include <iostream>
2 #include <cctype> // or ctype.h
3 #include "d_stack.h"
4
5 using namespace std;
6 void stackprocessing(Stack &);
7
8 int main()
9 {
10
11
12
13
14
15

Stack st1, st2; // create an empty stack


cout << "Stack #1 ##############################" <<
endl;
stackprocessing(st1);
if (st1.isempty() == false)
{
cout << "\n\nFirst stack is not empty, creating copy of it...." << endl;

16

st2 = st1;

17

Stack st3 = st2;

18
19

cout << "Stack #2 ##############################"


<< endl;

20
21
22
23

stackprocessing(st3);
}
else
cout << "\n\nFirst stack is empty, exitting...";

24
25
26

cout << "\nBye";

27

cin.get();

28

cin.get();

29

return 0;

30 }
31
32 void stackprocessing(Stack & st)
33 {
34

char ch;

35

unsigned long po;

36

cout << "Please enter A to add a purchase order,\n"

37

<< "P to process a PO, or Q to quit.\n";

38

while (cin >> ch && toupper(ch) != 'Q')

39

40

while (cin.get() != '\n')

41

continue;

42

if (!isalpha(ch))

43

44

cout << '\a';

45

continue;

46

47

switch(ch)

48

49

case 'A':

50

case 'a': cout << "Enter a PO number to add: ";

51

cin >> po;

52

if (st.isfull())

53
54

cout << "stack already full\n";


else

55
56

st.push(po);
break;

57

case 'P':

58

case 'p': if (st.isempty())

cout << "stack already empty\n";


59

else

60

61

st.pop(po);

62

cout << "PO #" << po << " popped\n";

63

64

break;

65

66

cout << "Please enter A to add a purchase order,\n"

67

<< "P to process a PO, or Q to quit.\n";

68

}
}

5. The Bank of Heather has performed a study showing that ATM customers
wont wait
more than one minute in line. Using the simulation from Listing 12.10, find a
value for
number of customers per hour that leads to an average wait time of one minute.
(Use at
least a 100-hour trial period.)
My answer:
queue.h
1

#ifndef QUEUE_H_

#define QUEUE_H_

// This queue will contain Customer items

class Customer

private:

long arrive; // arrival time for customer

int processtime; // processing time for customer

public:

10

Customer() { arrive = processtime = 0; }

11

void set(long when);

12

long when() const { return arrive; }

13

int ptime() const { return processtime; }

14 };
15
16 typedef Customer Item;
17
18 class Queue
19 {
20 private:
21

// class scope definitions

22

// Node is a nested structure definition local to this class

23

struct Node { Item item; struct Node * next;};

24

enum {Q_SIZE = 10};

25

// private class members

26

Node * front; // pointer to front of Queue

27

Node * rear; // pointer to rear of Queue

28

int items; // current number of items in Queue

29

const int qsize; // maximum number of items in Queue

30

// preemptive definitions to prevent public copying

31

Queue(const Queue & q) : qsize(0) { }

32

Queue & operator=(const Queue & q) { return *this;}

33 public:
34

Queue(int qs = Q_SIZE); // create queue with a qs limit

35

~Queue();

36

bool isempty() const;

37

bool isfull() const;

38

int queuecount() const;

39

bool enqueue(const Item &item); // add item to end

40

bool dequeue(Item &item); // remove item from front

41 };
42 #endif
queue.cpp
1 #include "queue.h"

2 #include <cstdlib> // (or stdlib.h) for rand()


3 Queue::Queue(int qs) : qsize(qs)
4 {
5

front = rear = NULL;

items = 0;

7 }
8 Queue::~Queue()
9 {
10

Node * temp;

11

while (front != NULL) // while queue is not yet empty

12

13

temp = front; // save address of front item

14

front = front->next;// reset pointer to next item

15

delete temp; // delete former front

16

17 }
18 bool Queue::isempty() const
19 {
20

return items == 0;

21 }
22 bool Queue::isfull() const
23 {
24

return items == qsize;

25 }
26 int Queue::queuecount() const
27 {
28

return items;

29 }
30 // Add item to queue
31 bool Queue::enqueue(const Item & item)
32 {
33

if (isfull())

34

return false;

35

Node * add = new Node; // create node

36

if (add == NULL)

37

return false; // quit if none available

38

add->item = item; // set node pointers

39

add->next = NULL;

40

items++;

41

if (front == NULL) // if queue is empty,

42

front = add; // place item at front

43

else

44

rear->next = add; // else place at rear

45

rear = add; // have rear point to new node

46

return true;

47 }
48 // Place front item into item variable and remove from queue
49 bool Queue::dequeue(Item & item)
50 {
51

if (front == NULL)

52

return false;

53

item = front->item; // set item to first item in queue

54

items--;

55

Node * temp = front; // save location of first item

56

front = front->next; // reset front to next item

57

delete temp; // delete former first item

58

if (items == 0)

59

rear = NULL;

60

return true;

61 }
62 // customer method
63 // when is the time at which the customer arrives
64 // the arrival time is set to when and the processing
65 // time set to a random value in the range 1 - 3

66 void Customer::set(long when)


67 {
68

processtime = std::rand() % 3 + 1;

69

arrive = when;

70 }
cp12ex5.cpp
1 #include <iostream>
2 #include <cstdlib> // for rand() and srand()
3 #include <ctime> // for time()
4 #include "queue.h"
5
6 const int MIN_PER_HR = 60;
7 bool newcustomer(double x); // is there a new customer?
8
9 int main()
10 {
11

using std::cin;

12

using std::cout;

13

using std::endl;

14

using std::ios_base;

15

// setting things up

16

std::srand(std::time(0)); // random initializing of rand()

17

cout << "Case Study: Bank of Heather Automatic Teller\n";

18

cout << "Enter maximum size of queue: ";

19

int qs;

20

cin >> qs;

21

Queue line(qs); // line queue holds up to qs people

22

cout << "Enter the number of simulation hours: ";

23

int hours; // hours of simulation

24

cin >> hours;

25

// simulation will run 1 cycle per minute

26

long cyclelimit = MIN_PER_HR * hours; // # of cycles

27

double perhour; // average # of arrival per hour

28

double min_per_cust; // average time between arrivals

29
30

//Item temp; // new customer data

31

long turnaways = 0; // turned away by full queue

32

long customers = 0; // joined the queue

33

long served = 0; // served during the simulation

34

long sum_line = 0; // cumulative line length

35

int wait_time = 0; // time until autoteller is free

36

long line_wait = 0; // cumulative time in line

37

double averagewait = 0;

38

// running the simulation, bruteforce method

39
40
41
42
43
44
45
46
47
48
49
50
51

// since values for processing times are random it will take a while, on
average 5-10 min of running this program, be patient
// sometimes it finds value very fast, again, because it's random
do
{
// reset all values for a new simulation loop
Item temp;
turnaways = 0; // turned away by full queue
customers = 0; // joined the queue
served = 0; // served during the simulation
sum_line = 0; // cumulative line length
wait_time = 0; // time until autoteller is free
line_wait = 0; // cumulative time in line

52
53
54

perhour = std::rand() % 60 + 1; // 60 ppl max per hour with 1 min of


waiting (average)
min_per_cust = MIN_PER_HR / perhour;

55
56
57
58

for (int cycle = 0; cycle < cyclelimit; cycle++)


{

59

if (newcustomer(min_per_cust)) // have newcomer

60

61

if (line.isfull())

62

turnaways++;

63

else

64

65

customers++;

66

temp.set(cycle); // cycle = time of arrival

67

line.enqueue(temp); // add newcomer to line

68

69

70

if (wait_time <= 0 && !line.isempty())

71

72

line.dequeue (temp); // attend next customer

73

wait_time = temp.ptime(); // for wait_time minutes

74

line_wait += cycle - temp.when();

75

served++;

76

77

if (wait_time > 0)

78

wait_time--;

79

sum_line += line.queuecount();

80

81
82
83
84
85
86
87
88
89
90

averagewait = (double) line_wait / served;


cout << "\nAverage wait: " << averagewait << ", Customers served: "
<< served;
}while (averagewait != 1.0); // runs until average wait is 0, which may
take up to 10 mins of real life time to find
// also you can try averagewait > 0.99 and averagewait < 1.1
// reporting results
if (customers > 0)
{
cout << "\n\n############ V A L U E F O U N D

91
92
93 #######################" << endl; // Success!!
94

cout << "customers accepted: " << customers << endl;

95

cout << " customers served: " << served << endl;

96

cout << " turnaways: " << turnaways << endl;

97

cout << "average queue size: ";

98

cout.precision(2);

99

cout.setf(ios_base::fixed, ios_base::floatfield);

10
0

cout.setf(ios_base::showpoint);

10
1

cout << " average wait time: "

10
2
10
3
10
4
10
5
10
6
10
7 }

cout << (double) sum_line / cyclelimit << endl;

<< averagewait << " minutes\n";


}
else
cout << "No customers!\n";

cout << "Done!\n";


cin.get();
cin.get();
return 0;

10 // x = average time, in minutes, between customers


8
// return value is true if customer shows up this minute
10
9 bool newcustomer(double x)
11 {
0
return (std::rand() * x / RAND_MAX < 1);
11 }
1
11
2

6. The Bank of Heather would like to know what would happen if it added a
second ATM.
Modify the simulation in this chapter so that it has two queues. Assume that a
customer
will join the first queue if it has fewer people in it than the second queue and that
the
customer will join the second queue otherwise. Again, find a value for number of
customers
per hour that leads to an average wait time of one minute. (Note: This is a
nonlinear
problem in that doubling the number of ATMs doesnt double the number of
customers who can be handled per hour with a one-minute wait maximum.)
My answer:
queue.h
1

#ifndef QUEUE_H_

#define QUEUE_H_

// This queue will contain Customer items

class Customer

private:

long arrive; // arrival time for customer

int processtime; // processing time for customer

public:

10

Customer() { arrive = processtime = 0; }

11

void set(long when);

12

long when() const { return arrive; }

13

int ptime() const { return processtime; }

14 };
15
16 typedef Customer Item;
17
18 class Queue
19 {
20 private:
21

// class scope definitions

22

// Node is a nested structure definition local to this class

23

struct Node { Item item; struct Node * next;};

24

enum {Q_SIZE = 10};

25

// private class members

26

Node * front; // pointer to front of Queue

27

Node * rear; // pointer to rear of Queue

28

int items; // current number of items in Queue

29

const int qsize; // maximum number of items in Queue

30

// preemptive definitions to prevent public copying

31

Queue(const Queue & q) : qsize(0) { }

32

Queue & operator=(const Queue & q) { return *this;}

33 public:
34

Queue(int qs = Q_SIZE); // create queue with a qs limit

35

~Queue();

36

bool isempty() const;

37

bool isfull() const;

38

int queuecount() const;

39

bool enqueue(const Item &item); // add item to end

40

bool dequeue(Item &item); // remove item from front

41 };
42 #endif
queue.cpp
1 #include "queue.h"
2 #include <cstdlib> // (or stdlib.h) for rand()
3 Queue::Queue(int qs) : qsize(qs)
4 {
5

front = rear = NULL;

items = 0;

7 }
8 Queue::~Queue()
9 {
10

Node * temp;

11

while (front != NULL) // while queue is not yet empty

12

13

temp = front; // save address of front item

14

front = front->next;// reset pointer to next item

15

delete temp; // delete former front

16

17 }
18 bool Queue::isempty() const
19 {
20

return items == 0;

21 }
22 bool Queue::isfull() const
23 {
24

return items == qsize;

25 }
26 int Queue::queuecount() const
27 {
28

return items;

29 }
30 // Add item to queue
31 bool Queue::enqueue(const Item & item)
32 {
33
34

if (isfull())
return false;

35

Node * add = new Node; // create node

36

if (add == NULL)

37

return false; // quit if none available

38

add->item = item; // set node pointers

39

add->next = NULL;

40

items++;

41

if (front == NULL) // if queue is empty,

42

front = add; // place item at front

43

else

44

rear->next = add; // else place at rear

45

rear = add; // have rear point to new node

46

return true;

47 }
48 // Place front item into item variable and remove from queue
49 bool Queue::dequeue(Item & item)
50 {
51

if (front == NULL)

52

return false;

53

item = front->item; // set item to first item in queue

54

items--;

55

Node * temp = front; // save location of first item

56

front = front->next; // reset front to next item

57

delete temp; // delete former first item

58

if (items == 0)

59

rear = NULL;

60

return true;

61 }
62 // customer method
63 // when is the time at which the customer arrives
64 // the arrival time is set to when and the processing
65 // time set to a random value in the range 1 - 3
66 void Customer::set(long when)
67 {
68

processtime = std::rand() % 3 + 1;

69

arrive = when;

70 }
cp12ex6.cpp
1 #include <iostream>
2 #include <cstdlib> // for rand() and srand()
3 #include <ctime> // for time()
4 #include "queue.h"

5
6 const int MIN_PER_HR = 60;
7 bool newcustomer(double x); // is there a new customer?
8
9 int main()
10 {
11

using std::cin;

12

using std::cout;

13

using std::endl;

14

using std::ios_base;

15

// setting things up

16

std::srand(std::time(0)); // random initializing of rand()

17

cout << "Case Study: Bank of Heather Automatic Teller\n";

18

cout << "Enter maximum size of queue: ";

19

int qs;

20

cin >> qs;

21

Queue line1(qs); // line queue holds up to qs people

22

Queue line2(qs);

23

cout << "Enter the number of simulation hours: ";

24

int hours; // hours of simulation

25

cin >> hours;

26

// simulation will run 1 cycle per minute

27

long cyclelimit = MIN_PER_HR * hours; // # of cycles

28

double perhour; // average # of arrival per hour

29

double min_per_cust; // average time between arrivals

30
31

//Item temp; // new customer data

32

long turnaways = 0; // turned away by full queue

33

long customers = 0; // joined the queue

34

long served = 0; // served during the simulation

35

long sum_line = 0; // cumulative line length

36

int wait_time1 = 0; // time until autoteller is free

37

int wait_time2 = 0;

38

long line_wait = 0; // cumulative time in line

39

double averagewait = 0;

40

// running the simulation, bruteforce method

41
42
43
44
45
46
47
48
49
50
51
52
53
54

// since values for processing times are random it will take a while, on
average 5-10 min of running this program, be patient
// sometimes it finds value very fast, again, because it's random
do
{
// reset all values for a new simulation loop
Item temp;
turnaways = 0; // turned away by full queue
customers = 0; // joined the queue
served = 0; // served during the simulation
sum_line = 0; // cumulative line length
wait_time1 = 0; // time until autoteller is free
wait_time2 = 0;
line_wait = 0; // cumulative time in line

55
56

perhour = std::rand() % 120 + 1; // 120 ppl max per hour for 2 lines with
1 min of waiting (average),

57

// higher numbers produce more randomness and longer time to find the
average
58
59

min_per_cust = MIN_PER_HR / perhour;

60
61

for (int cycle = 0; cycle < cyclelimit; cycle++)

62

63

if (newcustomer(min_per_cust)) // have newcomer

64

65
66
67
68

if (line1.isfull() && line2.isfull()) // if both lines are full, customer will


turn away
turnaways++;
else

69

70

customers++;

71

temp.set(cycle); // cycle = time of arrival

72
73
74

if (line1.queuecount() >= line2.queuecount()) // if line2 is


longer than line2
line2.enqueue(temp); // then bring customer to line 2 since
it's shorter

75

else

76

line1.enqueue(temp); // if otherwise, he'll join line 1

77
78
79
80

}
}
if (wait_time1 <= 0 && !line1.isempty()) // for line 1
{

81

line1.dequeue (temp); // attend next customer

82

wait_time1 = temp.ptime(); // for wait_time minutes

83

line_wait += cycle - temp.when();

84
85
86

served++;
}
if (wait_time1 > 0)

87

wait_time1--;

88

sum_line += line1.queuecount();

89
90
91

if (wait_time2 <= 0 && !line2.isempty()) // for line 2


{

92

line2.dequeue (temp); // attend next customer

93

wait_time2 = temp.ptime(); // for wait_time minutes

94

line_wait += cycle - temp.when();

95
96
97
98
99
10

served++;
}
if (wait_time2 > 0)
wait_time2--;
sum_line += line2.queuecount();

0
10
1
10
2

averagewait = (double) line_wait / served;


cout << "\nAverage wait: " << averagewait << ", Customers served: "
<< served;

10
3
if (averagewait > 0.999 && averagewait < 1.03) // value between 0.999
10
and 1.03 will be considered 1 min
4
break;
10
5
}while (perhour > 0);
10
6
10
7
10
8

// reporting results
if (customers > 0)
{

cout << "\n\n############ V A L U E F O U N D


10 #######################" << endl; // Success!!
9

cout << "customers accepted: " << customers << endl;

11
0

cout << " customers served: " << served << endl;

11
1

cout << "average queue size: ";

cout << " turnaways: " << turnaways << endl;

cout.precision(2);

11
2

cout.setf(ios_base::fixed, ios_base::floatfield);

11
3

cout.setf(ios_base::showpoint);
cout << (double) sum_line / cyclelimit << endl;

11
4
11
5
11
6
11
7

cout << " average wait time: "


<< averagewait << " minutes\n";
}
else
cout << "No customers!\n";

11
8

cout << "Done!\n";

11
9

cin.get();

cin.get();

12
0
12
1
12
2
12
3
12
4

return 0;

12
}
5
// x = average time, in minutes, between customers
12
6 // return value is true if customer shows up this minute
12 bool newcustomer(double x)
7
{
12
return (std::rand() * x / RAND_MAX < 1);
8
}
12
9
13
0
13
1
13
2
13
3

You might also like