Professional Documents
Culture Documents
Answers To Selected Exercises For Programming and Problem Solving With C++ 2004 PDF
Answers To Selected Exercises For Programming and Problem Solving With C++ 2004 PDF
Answers to
Selected Exercises
Chapter 1 Exam Preparation Exercises
1. a. v, b. i, c. viii, d. iii, e. iv, f. vii, g. vi, h. ii.
2. Analysis and specification, general solution (algorithm), verify.
3. Concrete solution (program), test.
4. The analysis and specification step within the problem-solving phase.
5. The steps never end. Changing the last step to say, “Repeat from first step until gradua-
tion,” converts the sequence into an algorithm that eventually ends, assuming the person
will graduate from school some day. We can make sure that this loop ends by specifying
a condition that will definitely occur. For example, “Repeat from first step until last day
of classes.”
6. a. vi, b. ii, c. v, d. i, e. vii, f. iv.
7. The program can be compiled on different computer systems without modification.
8. The control unit directs the actions of the other components in the computer to execute
program instruction in the proper order.
9. False. The editor is software rather than hardware.
10. False. Peripheral devices are external to the CPU and its main memory.
11. Yes. If the software license restricts use to a single computer or a single user, then this is
a case of piracy, even though you split the cost.
12. a. ii, b. v, c. iii, d. vii, e. i, f. vi, g. iv.
2. follow separate algorithm for filling glass with water and placing on counter
If right-handed,
pick up toothpaste tube in left hand and unscrew cap by turning counter-clockwise
place toothpaste cap on counter
transfer toothpaste tube to right hand and pick up toothbrush in left hand, holding it by its
handle
place open end of toothpaste tube against tips of brush bristles and squeeze toothpaste tube
just enough to create a 0.5-inch-long extrusion of toothpaste on brush
pull toothpaste tube away from brush and place tube on counter
transfer toothbrush to right hand, holding it by its handle
open mouth and insert brush, placing toothpaste-covered bristles against one tooth
scrub tooth with brush by moving brush up and down 10 times
reposition brush to an unscrubbed tooth
repeat previous two steps until all teeth have been brushed
spit toothpaste into sink
put toothbrush in sink
pick up glass in right hand
fill mouth with water from glass
swish water in mouth for five seconds
spit water from mouth into sink
repeat previous three steps three times
Otherwise (if left-handed)
pick up toothpaste tube in right hand and unscrew cap by turning counter-clockwise
place toothpaste cap on counter
transfer toothpaste tube to left hand and pick up toothbrush in right hand, holding it by its
handle
place open end of toothpaste tube against tips of brush bristles and squeeze toothpaste tube
just enough to create a 0.5-inch-long extrusion of toothpaste on brush
pull toothpaste tube away from brush and place tube on counter
transfer toothbrush to left hand, holding it by its handle
open mouth and insert brush, placing toothpaste-covered bristles against one tooth
scrub tooth with brush by moving brush up and down 10 times
reposition brush to an unscrubbed tooth
repeat previous two steps until all teeth have been brushed
spit toothpaste into sink
put toothbrush in sink
pick up glass in left hand
fill mouth with water from glass
swish water in mouth for five seconds
spit water from mouth into sink
repeat previous three steps three times
Place glass on counter
Follow separate algorithm for cleaning up after brushing teeth
DalePhatANS_complete 8/18/04 10:30 AM Page 1051
3. The test for right- or left-handedness is a branch. Each branch contains two loops, one
that iterates until all teeth are brushed and another that iterates rinsing four times. The
first and last steps refer to separately defined subalgorithms.
4. Change step u to:
u. Repeat step t nine times.
4. The template allows an identifier to begin with a digit. Identifiers can begin with a letter
or an underscore, and digits may appear only in the second character position and
beyond.
5. False.
6. True.
7. True.
8. Note that the second line concatenates two words without a separating space.
Four score and
seven years agoour fathers
brought forth on this
continent a new nation...
9. ”Bjarne Stroustrup named his new programming language C++ because it is a successor
to the C programming language.”
10. By preceding it with a backslash character (\”).
11. If we forget the */ at the end of a comment, then any number of lines of program code
can be inadvertently included in the comment. The // form avoids this by automatically
terminating at the end of the line.
12. The // form of comment cannot span more than one line. It also cannot be inserted into
the middle of a line of code because everything to the right of // becomes a comment.
13. << is the stream insertion operator, and is pronounced “put to” or “is sent,” as in “cout is
sent string4.”
14. No. The endl identifier is a manipulator, and is not a string value.
15. It tells the C++ preprocessor to insert the contents of a specified file at that point in the
code.
16. std::cout << "Hello everybody!" << std::endl;
17. A block.
18. By splitting it into pieces that fit on a line, and joining them with the concatenation
operator.
19. #include <iostream>
#include <string>
2. Note that the \" escape sequence is needed in six places here:
cout << "He said, \"How is that possible?\"" << endl
<< "She replied, \"Using manipulators.\"" << endl
<< "\"Of course,\" he exclaimed!" << endl;
3. a. const string ANSWER = "True";
b. char middleInitial;
c. string courseTitle;
d. const char PERCENT = '%'
4. const string FIRST = "Your first name inserted here";
const string LAST = "Your last name inserted here";
// Insert your middle initial in place of A:
const char MIDDLE = 'A';
8. #include <iostream>
#include <string>
int main()
{
cout << TITLE << FIRST << DOT << MID << DOT
<< " Jones";
}
9. The solution to this problem is for the student to show that he or she has run the pro-
gram correctly. It should output:
***********************************
* *
* Welcome to C++ Programming! *
* *
***********************************
DalePhatANS_complete 8/18/04 10:30 AM Page 1054
5.
//******************************************************************
// Chessboard program
// This program prints a chessboard pattern that is built up from
// basic strings of white and black characters.
//******************************************************************
#include <iostream>
#include <string>
return 0;
}
6. There are 64 characters per line, except for the results of Exercise 4, which would have
80 characters per line.
5.
integer / constant /
floating variable
a. const int TRACKS_ON_DISK = 17; integer constant
b. float timeOfTrack; floating variable
c. const float MAX_TIME_ON_DISK = 74.0; floating constant
d. short tracksLeft; integer variable
e. float timeLeft; floating variable
f. long samplesInTrack; integer variable
g. const double SAMPLE_RATE = 262144.5; floating constant
6. Integer division with an integer result, and floating division with a floating result.
7. a. 21, b. 21.6, c. 13.0, d. 18, e. 20, f. 22, g. 18.0.
8. () unary - [ * / % ] [ + - ]
9. True.
10. a. vi, b. ii, c. vii, d. iv, e. i, f. v, g. iii.
11. The ++ operator.
12. You write the name of a data type, followed by an expression enclosed in parentheses.
13. main returns an int value.
14. 215.00
15. False. When used alone they are equivalent, but used within a larger expression, they can
give different results (this is explained more in Chapter 10).
16. string::size_type
17. a. 29
b. 1
c. "ought to start with logic"
d. 0
e. "log"
f. 1
g. string::npos
18. It tells the stream to print floating-point numbers without using scientific notation.
e. sqrt(fabs(A – B))
f. pow(X, -cos(Y))
7. string temp;
temp = sentence;
first = temp.find("and"); // Get first location
second = temp.find("and");
12. //**********************************************
// Celsius program
// This program outputs the Celsius temperature
// corresponding to a given Fahrenheit temperature
//**********************************************
#include <iostream>
int main()
{
const float FAHRENHEIT = 72.0;
DalePhatANS_complete 8/18/04 10:30 AM Page 1059
float celsius;
2. Change the NUMBER_OF_YEARS to NUMBER_OF_MONTHS with the value 84. Remove num-
berOfPayments and substitute NUMBER_OF_MONTHS where numberOfPayments
occurs. Change
...
const float LOAN_AMOUNT = 50000.00; // Amount of the loan
const float YEARLY_INTEREST = 0.0524; // Yearly interest rate
const int NUMBER_OF_MONTHS = 84; // Total number of payments
int main()
{
// local variables
// Calculate values
// Output results
cout << fixed << setprecision(2) << "For a loan amount of "
<< LOAN_AMOUNT << " with an interest rate of "
<< setprecision(4) << YEARLY_INTEREST << " and a "
DalePhatANS_complete 8/18/04 10:30 AM Page 1060
3. ...
const float LOAN_AMOUNT = 50000.00; // Amount of the loan
const float YEARLY_INTEREST = 5.24; // Yearly interest rate
const int NUMBER_OF_MONTHS = 84; // Total number of payments
int main()
{
// local variables
float monthlyInterest; // Monthly interest rate
float payment; // Monthly payment
// Calculate values
monthlyInterest = YEARLY_INTEREST * 0.01 / 12;
payment = (LOAN_AMOUNT * pow(monthlyInterest + 1,
NUMBER_OF_MONTHS)
* monthlyInterest)/(pow(monthlyInterest + 1, NUMBER_OF_MONTHS)
- 1 );
// Output results
cout << fixed << setprecision(2) << "For a loan amount of "
<< LOAN_AMOUNT << " with an interest rate of "
<< YEARLY_INTEREST << " and a "
<< NUMBER_OF_MONTHS << " month mortgage, " << endl;
cout << "your monthly payments are $" << payment << "."
<< endl;
...
}
4. ...
float onePlus; // Monthly interest plus 1
// Calculate values
onePlus = monthlyInterest + 1;
payment = (LOAN_AMOUNT * pow(onePlus, NUMBER_OF_MONTHS) *
monthlyInterest/(pow(onePlus, NUMBER_OF_MONTHS) - 1;
...
DalePhatANS_complete 8/18/04 10:30 AM Page 1061
b. The reading marker is on the newline character at the end of the line.
8. It returns \n.
9. The first argument is a maximum number of characters to skip over. The second argu-
ment specifies a character that the function searches for. If it finds the character before
skipping the maximum number of characters, then it stops with the reading marker on
the following character.
10. Some variation in the answer is acceptable, as long as it is clear that the prompt for the
inexperienced user is much more detailed.
a. cout << "Enter a date in the format of mm/dd/yyyy."
<< " For example, for October 18, 1989, enter 10/18/1989.";
b. cout << "Enter date, format mm/dd/yyyy.";
11. Include the header file fstream. Declare the file stream. Prepare the file with open.
Specify the name of the file stream in each I/O statement.
12. ifstream and ofstream.
13. The first statement declares inFile to be an input file stream. The second statement
opens inFile, associating it with a file called datafile.dat by the operating system.
14. The correction is to convert the name into a C string.
ifstream inData;
string name;
4. float number1;
float number2;
float number3;
float average;
cout << "Enter the first number and press return: ";
cin >> number1;
cout << "Enter the second number and press return: ";
cin >> number2;
cout << "Enter the third number and press return: ";
cin >> number3;
average = (number1 + number2 + number3) / 3.0;
cout << "The average is: " << average << endl;
5. float number1;
float number2;
float number3;
float average;
6. The names of the variables may differ from those shown here. Instead of using the ignore
function to skip a single character, reading into a dummy char variable may also be
used.
a. int int1;
char char1;
float float1;
b. string string1;
string string2;
int int1;
int int2;
c. int int1;
int int2;
float float1;
d. char char1;
char char2;
char char3;
char char4;
e. float float1;
cin.ignore(1, '$');
cin >> float1;
DalePhatANS_complete 8/18/04 10:30 AM Page 1064
8. #include <fstream>
fstream temps;
temps.open("temperatures.dat");
9. An alternative approach is to declare one temp variable that is reused for each of six
input statements, and keep a running total of the input values.
float temp1;
float temp2;
float temp3;
float temp4;
float temp5;
float temp6;
float average;
temps >> temp1 >> temp2 >> temp3 >> temp4 >> temp15 >> temp6;
average = (temp1 + temp2 + temp3 + temp4 + temp5 + temp6) / 6.0;
cout << "The average temperature is: " << average;
fstream inData;
fstream outData;
const float PI = 3.14159265;
float radius;
float circumference;
float area;
int main()
{
inData.open("indata.dat");
outData.open("outdata.dat");
inData >> radius;
circumference = radius * 2 * PI;
area = radius * radius * PI;
cout << "For the first circle, the circumference is "
<< circumference << " and the area is " << area << endl;
outData << radius << " " << circumference << " " << area << endl;
inData >> radius;
DalePhatANS_complete 8/18/04 10:30 AM Page 1065
fstream inData;
fstream outData;
const float PI = 3.14159265;
float radius;
float circumference;
float area;
string filename;
int main()
{
inData.open("indata.dat");
cout << "Enter the name of the file to open: ";
outData.open(filename.c_str());
14.
Top level:
Write letter
Mail letter
DalePhatANS_complete 8/18/04 10:30 AM Page 1066
Level 2
Write letter
Mail letter
Address envelope
Write return address
Attach stamp to envelope
Fold letter in thirds
Insert letter in envelope
Seal envelope
Place envelope in mail box
15. Letter and envelope are the main objects. Other objects include: return address, company
address, salutation, letter body, closing, signature, stamp, and mail box.
ifstream inData;
ofstream outData;
string fileName;
cout << "Enter the name of the input file: ";
DalePhatANS_complete 8/18/04 10:30 AM Page 1067
5. //******************************************************************
// Mortgage Payment Calculator program
// This program determines the monthly payments on a mortgage given
// the loan amount, the yearly interest, and the number of years.
//******************************************************************
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main()
{
// Input variables
float loanAmount;
float yearlyInterest;
int numberOfYears;
// local variables
float monthlyInterest;
int numberOfPayments;
float payment;
DalePhatANS_complete 8/18/04 10:30 AM Page 1068
cout << "Input the total loan amount (ex: 50000.00)" << endl;
cin >> loanAmount;
cout << "Input the interest rate (ex: 6.25)" << endl;
cin >> yearlyInterest;
cout << "Enter the number of years for the loan (ex: 15)"
<< endl;
cin >> numberOfYears;
// Calculate values
// Output results
cout << fixed << setprecision(2) << "For a loan amount of "
<< loanAmount
<< " with an interest rate of " << yearlyInterest
<< " and a "
<< numberOfYears << " year mortgage, " << endl;
cout << fixed << setprecision(2)
<< "your monthly payments are $"
<< payment << "." << endl;
return 0;
}
f. true
g. true
6. a. true
b. true
c. true
d. true
e. true
f. false
g. false
7. Because conditional or short-circuit evaluation prevents the second part of the expres-
sion from being evaluated when someInt is 0.
8. True.
9. False. The parentheses are required.
10. It outputs “The data doesn't make sense."
11. It outputs The word may be "The"
12. Nothing.
13. Because the test is written with = instead of ==, so the expression is always false.
14. It outputs Very good
15. Very goodExcellent
16. Add braces to enclose the If-Then statement.
17. !inData
18. There is no limit, although a human reader finds it difficult to follow too many levels.
4. if (year1 < year2 && month1 < month2 && day1 < day2)
cout << month1 << "/" << day1 << "/" year1
<< " comes before "
<< month2 << "/' << day2 << "/" << year2;
else
cout << month1 << "/" << day1 << "/" year1
<< " does not come before "
<< month2 << "/' << day2 << "/" << year2;
5. if (year1 < year2 && month1 < month2 && day1 < day2)
cout << month1 << "/" << day1 << "/" year 1
<< " comes before "
<< month2 << "/' << day2 << "/" << year2;
else
{
cout << month1 << "/" << day1 << "/" year1
<< " does not come before "
DalePhatANS_complete 8/18/04 10:31 AM Page 1070
<< month2 << "/' << day2 << "/" << year2;
month1 = month2;
day1 = day2;
year1 = year2;
}
12. The conditional tests are using = instead of ==. Both branches have the error, but the sec-
ond one doesn’t output the message because the result of the assignment expression is 0,
which is treated as false by the branch.
maximum = 75;
minimum = 25;
if (maximum == 100)
cout << "Error in maximum: " << maximum << endl;
if (minimum == 0)
cout << "Error in minimum: " << minimum << endl;
14. Values of temp that should be tried are: 213, 212, 211, 33, 32, 31.
15. Combinations of values for month, day, and year that should be tested are as follows:
#include <iostream>
int main()
{
// Test Data
if (dataAreOK)
{
// Calculate body mass index
cout << "Your body mass index is " << bodyMassIndex << ". "
<< endl;
cout << "Interpretation and instructions. " << endl;
if (bodyMassIndex < 18.5)
cout << "Underweight: Have a milkshake." << endl;
else if (bodyMassIndex < 25.0)
cout << "Normal: Have a glass of milk." << endl;
else if (bodyMassIndex < 30.0)
cout << "Overweight: Have a glass of iced tea." << endl;
else
cout << "Obese: See your doctor." << endl;
}
else
cout << "Invalid data; weight and height must be positive."
<< endl;
return 0;
}
4. //******************************************************************
// BMI Program
// This program calculates the body mass index (BMI) given a weight
// in pounds and a height in feet and inches and prints a health
// based message on the BMI. Input in English measures.
//******************************************************************
#include <iostream>
int main()
{
const int BMI_CONSTANT = 703; // Constant in nonmetric formula
float weight; // Weight in pounds
float inches; // Remainder of height in inches
float feet; // Height in feet
float height; // Complete height in inches
float bodyMassIndex; // Appropriate BMI
bool dataAreOK; // True if data non-negative
DalePhatANS_complete 8/18/04 10:31 AM Page 1074
// Test Data
if (dataAreOK)
{
// Calculate body mass index
5. The weight and height are checked to be sure they are not negative before the BMI is cal-
culated in this program. There are several other things that could be done. For example,
if the weight is less than the height, then there is an error. In fact, if the weight is less
than one and a half times the height, there is a good chance that there is an error. This
condition produces very low BMIs. What about weights that are six or seven times the
height? These produce very high BMIs. Another approach would be to put a check on
the BMI itself. If it is below 10 or greater than 60, there is a good chance of input errors.
6. Twelve times.
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
7. Twelve times.
$1.00
$2.00
$3.00
$4.00
$5.00
$6.00
$7.00
$8.00
$9.00
$10.00
$11.00
$12.00
DalePhatANS_complete 8/18/04 10:31 AM Page 1076
10. The code fails to process the first value on the file. The corrected code is:
sum = 0;
indata >> number;
while (indata)
{
sum = sum + number;
indata >> number;
}
11. You could choose anything that’s not a name. A blank line would be one possibility. If
the program must read the name in three parts, then a series of nonalphabetic characters,
separated appropriately, would work. For example: 999 888 777.
12. The output is:
3 5 7 9 11 13 15 17 19
{
cout << number * 2 – 1 << " ";
number++;
}
13. False.
14. What is the condition that ends the loop? How should the condition be initialized? How
should the condition be updated? What is the process being repeated? How should the
process be initialized? How should the process by updated? What is the state of the pro-
gram on exiting the loop?
15. The sum is not reinitialized at the start of each inner loop, so it simply keeps accumulat-
ing the input values. The count isn’t updated, so the flow of control doesn’t leave the
inner loop until the end-of-file condition is encountered. Here is the corrected code.
while (indata)
{
count = 1;
sum = 0;
while (count <= 5 && indata)
{
cin >> number;
sum = sum + number;
count++;
}
cout << sum / count << endl;
}
2. count = 1;
sum = 0;
while (sum <= 10000)
{
sum = sum + count;
count++;
}
cout << count – 1;
DalePhatANS_complete 8/18/04 10:31 AM Page 1078
3. count = 0;
sum = 0;
indata >> score;
while (indata && count < 20)
{
sum = sum + score;
count++;
indata >> score;
}
if (count == 0)
cout << "No data on file.";
else
cout << "Average is " << sum / count << endl;
4. count = 0;
getline(chapter6, line);
while (chapter6)
{
if (line.find("code segment") < string::npos)
count++;
getline(chapter6, line);
}
cout << "The string was found " << count << " times."
6. cout << "Sun Mon Tue Wed Thu Fri Sat" << endl;
count = 1;
while (count <= startDay) //Print blanks in first week
{
cout << " ";
count++;
}
dayNumber = 1;
while (dayNumber <= days) //Print day numbers for month
{
while (count <= 7) //Print for one week in month
{
if (dayNumber <= days)
DalePhatANS_complete 8/18/04 10:31 AM Page 1079
9. char oneChar;
int eCount;
int charCount;
eCount = 0;
textData >> oneChar;
charCount = 0;
while (textData && charCount < 10000)
{
charCount++;
if (oneChar == 'z')
eCount++;
textData >> oneChar;
}
cout << "Percentage of letter 'z': "
{
next = first + second;
first = second;
second = next;
cout << second << endl;
}
11. first = 1;
second = 1;
cout << setw(5) << 1 << setw(8) << first << endl
<< setw(5) << 1 << setw(8) << second << endl;
position = 2;
while (second < 30000)
{
next = first + second;
first = second;
second = next;
position++;
cout << setw(5) << position << setw(8) << second << endl;
}
13. The loop ends when the specified number of stars has been printed. The condition is ini-
tialized by getting the number of stars, and setting the loop iteration counter to 1. The
condition is updated by incrementing the iteration counter at the end of each iteration.
The process being repeated is the printing of a single star. The process does not require
any initialization or update. Upon exiting the loop, the specified number of stars has
been printed, and the iteration counter is equal to the number plus one.
14. indata >> number;
while (indata)
{
count = 1;
while (count <= number)
{
cout << '*';
count++;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1081
15. The code should be tested with an empty file, a file that contains one value, and a file
that contains multiple values. The values should include a negative integer, zero, and
positive integers.
9. False. Arguments must appear in the same order as the corresponding parameters.
10. Hiding a module implementation in a separate block with a formally specified interface.
11. Flow out, or in and out.
12. It should not contain a return statement.
13. The result is not passed back to the caller—it should be a reference parameter instead of a
local variable.
14. The result is not passed back to the caller—result should be a reference parameter
instead of a value parameter.
15. The x and y parameters should be value parameters—their data flow is inward only. In the
case of the y parameter, the value of the argument will be set to zero when the function
returns.
16. False. Like any other variable declaration, it can be accessed only by statements within
the block that follows its declaration.
17. True.
18. That the file contains valid data (only integers), and that it has at least one value (the
mean is undefined for an empty data set).
7. // Precondition:
// File infile has been opened AND
// header file climits has been included
// Postcondition:
// File infile is at end-of-file AND
// if the file is empty, lowest contains INT_MAX;
// else smallest number on file infile is in lowest
11. // Precondition:
// Original must have a value
// Postcondition:
// lanigiro contains the reverse of the string in original
13. // Precondition:
// The program has included the header cctype
// Postcondition:
// A line has been read from cin AND
// the number of lowercase letters on the line is in count
/* in */ int addDays,
/* in */ int addHours,
/* in */ int addMinutes,
/* in */ int addSeconds)
{
int extraMinute;
int extraHour;
int extraDay;
seconds = (seconds + addSeconds) % 60;
extraMinute = (seconds + addSeconds) / 60;
minutes = (minutes + addMinutes + extraMinute) % 60;
extraHour = (minutes + addMinutes + extraMinute) / 60;
hours = (hours + addHours + extraHour) % 24;
extraDay = (hours + addHours + extraHour) / 24;
days = days + addDays + extraDay;
}
#include <iostream>
#include <cmath>
#include <iomanip>
#include <fstream>
using namespace std;
DalePhatANS_complete 8/18/04 10:31 AM Page 1086
// Function prototypes
void PrintHeading(ofstream&);
void GetLoanAmount(float&);
void GetRestOfData(float&, int&);
void DeterminePayment(float, int, float, float&);
void PrintResults(ofstream&, float, int, float, float);
int main()
{
// Input variables
float loanAmount;
float yearlyRate;
int numberOfYears;
float payment;
ofstream dataOut;
dataOut.open("mortgage.out");
PrintHeading(dataOut);
//******************************************************************
dataOut << fixed << setprecision(2) << setw(12) << "Loan Amount"
<< setw(12) << "No. Years" << setw(15)
<< "Interest Rate" << setw(12) << "Payment"
<< setw(12) << "Total Paid" << endl;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1087
//******************************************************************
//******************************************************************
//******************************************************************
{
// local variables
float monthlyRate;
int numberOfPayments;
monthlyRate = yearlyRate / 1200;
numberOfPayments = numberOfYears * 12;
payment = (loanAmount
* pow(1 + monthlyRate, numberOfPayments)
* monthlyRate)
/ (pow(1 + monthlyRate, numberOfPayments) - 1 );
}
//******************************************************************
//******************************************************************
Clearly, values that do not make sense cause problems. inf and nan are C++ special
symbols that mean infinite and undefined. Loan amount, number of years, and interest
rate should be greater than zero.
3. Error checking has three parts: what is an error, where do you check for it, and what do
you do when it occurs. In this case, a nonpositive value for any of the inputs is an error,
and the errors should be checked for immediately after the values are input. What should
you do when nonpositive values are input? You have several choices. You can prompt
the user to re-enter the bad value, enclosing the reading within a loop. Of course, if a
correct value is never input, an infinite loop occurs. Another option is to write an error
message and stop the program; for example, you can add a Boolean variable to each
input function that returns true if the value(s) are OK and false otherwise. After each call,
this variable can be checked before the program continues.
Because there are so many possible solutions, we do not show one. Check over yours
and be sure you have the three parts.
4. void PrintResults( /* inout */ ofstream& dataOut, // Output file
/* in */ float loanAmount, // Loan amount
/* in */ int numberOfYears, // Term of loan
/* in */ float yearlyRate, // Interest rate
/* in */ float payment ) // Payment
{
float amountPaid;
DalePhatANS_complete 8/18/04 10:31 AM Page 1089
amountPaid = numberOfYears*12*payment;
dataOut << fixed << setprecision(2) << setw(12) << loanAmount
<< setw(12) << numberOfYears << setw(12)
<< yearlyRate << setw(15) << payment
<< setw(12) << amountPaid << setw(12)
<< amountPaid - loanAmount << endl;
}
int main ()
{
int pow;
int x;
9. int LowerCount ()
{
char inChar;
int count;
count = 0;
cin >> inChar;
while (cin && inChar != '\n')
{
if (islower(inChar))
count++;
cin >> inChar;
}
return count;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1092
//******************************************************************
void EvaluateBloodPressure
( /* inout */ ofstream& healthProfile, // Output file
/* in */ string name ) // Patient's name
{
// Declare the health statistics
int systolic;
int diastolic;
3. //******************************************************************
// Profile Program
// This program inputs a name, weight, height, blood pressure
// readings, and cholesterol values. If an input value is
// negative, an error message is written. Appropriate health
// messages are written for each of the input values.
//******************************************************************
DalePhatANS_complete 8/18/04 10:31 AM Page 1096
#include <fstream>
#include <iostream>
#include <string>
string Name();
void EvaluateCholesterol(ofstream& healthProfile, string name,
bool& dataOK);
void EvaluateBMI(ofstream& healthProfile, string name,
bool& dataOK);
void EvaluateBloodPressure(ofstream& healthProfile, string name,
bool& dataOK);
int main()
{
// Declare and open the output file
ofstream healthProfile;
healthProfile.open("Profile");
string name;
bool dataOK;
name = Name();
//******************************************************************
// Name function
// This function inputs a name and returns it in first,
// middle initial, and last order.
//******************************************************************
string Name()
{
// Declare the patient's name
string firstName;
string lastName;
char middleInitial;
DalePhatANS_complete 8/18/04 10:31 AM Page 1097
//******************************************************************
// Cholesterol function
// This function inputs HDL (good cholesterol) and LDL (bad
// cholesterol) and prints out a health message based on their
// values on file healthProfile.
//******************************************************************
void EvaluateCholesterol
( /* inout */ ofstream& healthProfile, // Output file
/* in */ string name, // Patient's name
/* out */ bool& dataOK)
{
int HDL;
int LDL;
cout << "Enter HDL for " << name << ": ";
cin >> HDL;
cout << "Enter LDL for " << name << ": ";
cin >> LDL;
else
healthProfile << " HDL is excellent" << endl;
//******************************************************************
// BMI Function
// This function inputs weight in pounds and height in inches and
// calculates the body mass index (BMI prints a health message
// based on the BMI. Input in English weights.
//******************************************************************
void EvaluateBMI
( /* inout */ ofstream& healthProfile, // Output file
/* in */ string name, // Patient's name
/* out */ bool& dataOK)
{
const int BMI_CONSTANT = 703; // Constant in English formula
float pounds;
float inches;
cout << "Enter the weight in pounds for " << name << ": ";
cin >> pounds;
cout << "Enter the height in inches for " << name << ": ";
cin >> inches;
DalePhatANS_complete 8/18/04 10:31 AM Page 1099
if ( !dataOK)
cout << " BMI data must be positive; test aborted. ";
else
{
float bodyMassIndex = pounds * BMI_CONSTANT /
(inches * inches);
healthProfile << "Body Mass Index Profile" << endl;
//******************************************************************
// Blood Pressure function
// This function gets blood pressure readings (systolic/diastolic)
// and prints out a health message based on their values
// in file healthProfile.
//******************************************************************
void EvaluateBloodPressure
( /* inout */ ofstream& healthProfile, // Output file
/* in */ string name, // Patient's name
/* out */ bool& dataOK)
{
// Declare the health statistics
int systolic;
DalePhatANS_complete 8/18/04 10:31 AM Page 1100
int diastolic;
// Enter the patient's health statistics
cout << "Enter the systolic blood pressure reading for "
<< name << ": ";
cin >> systolic;
cout << "Enter the diastolic blood pressure reading for "
<< name << ": ";
cin >> diastolic;
if ( !dataOK )
cout << " Blood pressure data must be positive;"
<< " test aborted. ";
else
{
healthProfile << "Blood Pressure Profile " << endl;
if (systolic < 120)
healthProfile << " Systolic reading is optimal"
<< endl;
else if (systolic < 130)
healthProfile << " Systolic reading is normal"
<< endl;
else if (systolic < 140)
healthProfile << " Systolic reading is high normal"
<< endl;
else if (systolic < 160)
healthProfile
<< " Systolic indicates hypertension Stage 1"
<< endl;
else if (systolic < 180)
healthProfile
<< " Systolic indicates hypertension Stage 2"
<< endl;
else
healthProfile
<< " Systolic indicates hypertension Stage 3"
<< endl;
14. 2
1
0
3
2
1
4
3
2
2. switch (day)
{
case 0 : cout << "Sunday"; break;
case 1 : cout << "Monday"; break;
case 2 : cout << "Tuesday"; break;
case 3 : cout << "Wednesday"; break;
case 4 : cout << "Thursday"; break;
case 5 : cout << "Friday"; break;
case 6 : cout << "Saturday"; break;
default: cout << "Error";
}
3. Note that Break statements aren’t needed because each branch of the Switch exits the
function, accomplishing the required effect.
string DayOfWeek (/* in */ int day)
{
switch (day)
{
case 0 : return "Sunday";
case 1 : return "Monday";
case 2 : return "Tuesday";
case 3 : return "Wednesday";
case 4 : return "Thursday";
case 5 : return "Friday";
case 6 : return "Saturday";
default: return "Error";
}
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1104
6. char response;
do
{
cout << "Please enter 'Y' or 'N': ";
cin >> response;
if (response != 'Y' && response != 'N')
cout << "Invalid response. ";
} while (response != 'Y' && response != 'N');
{
star = 1;
do
{
cout << '*';
star++;
} while (star <= line);
cout << endl;
line++;
} while (line <= 10);
15. Exercise 13 outputs 255 lines, and Exercise 14 outputs 15,300 lines.
DalePhatANS_complete 8/18/04 10:31 AM Page 1107
2. Words are ended by punctuation marks, blanks, or end of lines. A sum of these gives an
estimate of the number of words.
3. Average word length would be the total number of alphanumeric characters divided by
the number of words.
4. Average sentence length, percentage of two-character words, percentage of three-charac-
ter words, percentage of words over a certain threshold—all of these would be good can-
didates.
2. a. 3.14159265F
b. 3.14159265
c. 3.14159265L
d. 3.14159265E0
3. a. days += 7;
b. radius *= 6.2831853;
c. workHours -= 40;
d. average /= count;
4. sizeof(long) * 8
5. a. a * b + c * d
b. a * b / (c * d)
c. a + b + c / (d + e) * f
d. (a + b) / (c + d) * (e + f)
e. -a + b <= c * d && a + b >= c – d
6. cin >> charIn;
if (isdigit( charIn))
numIn = charIn – '0';
7. int eCount;
string::size_type pos;
eCount = 0;
for (pos = 0; pos < inLine.length(); pos++)
if (inline[pos] == 'e')
eCount++;
9. if (tolower(ampm[0]) == 'p')
hours = hours + 12;
#include <fstream>
#include <iostream>
#include <iomanip>
#include <cctype>
int main()
{
// Prepare files for reading and writing
ifstream text;
ofstream table;
OpenFiles(text, table);
char character;
//******************************************************************
// Function Decode examines the character and returns its type
DalePhatANS_complete 8/18/04 10:31 AM Page 1112
if (hyphen)
{
hyphen = false;
if (character == '\n')
return IGNORE;
else
return COMPOUND;
}
if (isupper(character))
return UPPER;
else if (islower(character))
return LOWER;
else if (isdigit(character))
return DIGIT;
else
switch (character)
{
case '.' :
case '?' :
case '!' : return EOS;
}
return IGNORE;
}
//******************************************************************
// Function OpenFiles reads in the names of the input file and the
// output file and opens them for processing.
{
string inFileName;
string outFileName;
cout << "Enter the name of the file to be processed" << endl;
cin >> inFileName;
text.open(inFileName.c_str());
cout << "Enter the name of the output file" << endl;
cin >> outFileName;
table.open(outFileName.c_str());
table << "Analysis of characters on input file " << inFileName
<< endl << endl;
}
//******************************************************************
// Function PrintTable prints the percentages represented by each
// of the five categories
void PrintTable
( /* inout */ ofstream& table, // Output file
/* in */ int uppercaseCounter, // Uppercase letters
/* in */ int lowercaseCounter, // Lowercase letters
/* in */ int digitCounter, // Digits
/* in */ int sentenceCounter, // '.', '?', '!'
/* in */ int wordCounter, // Words
/* in */ int ignoreCounter ) // Everything else
{
int totalAlphaNum;
totalAlphaNum = uppercaseCounter + lowercaseCounter +
digitCounter;
// Print results on file table
table << "Total number of alphanumeric characters: "
<< totalAlphaNum
<< endl;
table << "Number of uppercase letters: " << uppercaseCounter
<< endl;
table << "Number of lowercase letters: " << lowercaseCounter
<< endl;
table << "Number of digits: " << digitCounter << endl;
table << "Number of characters ignored: " << ignoreCounter
<< endl;
table << "Average word length: " << fixed << setprecision(2)
<< float(totalAlphaNum)/wordCounter << endl;
table << "Average sentence length: " << fixed \
<< setprecision(2)
<< float(wordCounter)
/ sentenceCounter << endl;
//******************************************************************
// Function ProcessCharacter examines character and increments the
// appropriate counter.
void ProcessCharacter
( /* in */ char character, // Character to be
// processed
/* inout */ int uppercaseCounter, // Uppercase letters
/* inout */ int lowercaseCounter, // Lowercase letters
/* inout */ int digitCounter, // Digits
/* inout */ int sentenceCounter, // '.', '?', '!'
/* inout */ int wordCounter, // Words
/* inout */ int ignoreCounter ) // Everything else
{
static bool endOfWord = false;
switch (Decode(character))
{
case UPPER : uppercaseCounter++;
endOfWord = false;
break;
case LOWER : lowercaseCounter++;
endOfWord = false;
break;
case DIGIT : digitCounter++;
endOfWord = false;
break;
case EOW : if (!endOfWord)
{
wordCounter++;
endOfWord = true;
}
break;
DalePhatANS_complete 8/18/04 10:31 AM Page 1115
case EOS :
sentenceCounter++;
endOfWord = true;
break;
case IGNORE: ignoreCounter++;
break;
case COMPOUND :
wordCounter++;
switch (Decode(character))
{
}
}
However, it takes about the same amount of time to just set it to the same value.
5. This program looks at each character in a file and classifies it as an uppercase letter, a
lowercase letter, a digit, an end-of-sentence symbol, an end-of-word symbol, or a
hyphen in the expanded version in Exercise 3. No errors can occur in classifying each
character, so no error detection is necessary. There may be logic errors in the determina-
tion of the number of words and sentences, but no error detection would find these.
b. sally.gradeNumber = 7;
c. spring = sally.grades[3]
9. All of the fields of the struct are copied to the value parameter, and the function works
with the copy. Only the address of the struct would be passed to the reference parame-
ter, and the function would have direct access to the fields of the struct.
10. a. Makes the type of grade be char, and inputs a char to grade.
b. Compares the value in grade to see if it is in the range of ‘A' through ‘D'.
c. Computes the integer equivalent of the letter grade, changes the type of grade to
int, and assigns the numeric value to it.
11. Its domain and operations.
12. The data representation is a concrete form of the domain, expressed in terms of structures
and types supported by the programming language.
13. Private.
14. current.plus(period);
15. Observers, because they do not change the private data.
16. By matching the number, order, and types of the arguments with the parameter list.
17. Calendar primary;
Calendar primary(2004);
2. someTime.minutes = 6;
someTime.seconds = 54;
3. struct Song
{
string title;
string album;
string artist;
Time playTime;
Category type;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1117
4. Song mySong;
7. Temporal shift;
shift = someTime;
8. //*****************************************
// SPECIFICATION FILE (Period)
// This file gives the specification of a
// class for geologic time periods
//*****************************************
class Period
{
public:
enum PeriodName { PRECAMBRIAN, CAMBRIAN, ORDOVICIAN,
SILURIAN, DEVONIAN, CARBONIFEROUS,
PERMIAN, TRIASSIC, JURASSIC,
CRETACEOUS, TERTIARY, QUATERNARY};
Period();
// Default constructor
// Creates object with value PRECAMBRIAN
Period(PeriodName);
// Constructor
// Creates object with value specified
void Increment();
// Transformer
// Advances value of object to next most recent period
// Won't advance past QUATERNARY
private:
PeriodName thisPeriod;
9. Period quaternary(QUATERNARY);
for (Period count; count.ToInt() <= quaternary.ToInt();
count.Increment())
cout << count.ToString() << ": " << count.StartDate() << endl;
10. Period::Period()
// Default constructor
// Creates object with value PRECAMBRIAN
{
PeriodName = PRECAMBRIAN;
}
14. //*****************************************
// SPECIFICATION FILE (Money)
// This file gives the specification of a
// class for representing money as dollars
// and cents using integers.
//*****************************************
class Money
{
public:
Money();
// Default constructor
// Creates object with value $0.00
Money(int, int);
// Constructor
// Creates object with value specified
// in dollars and cents
void Add(Money);
// Transformer
// Adds value of money object in parameter
void Sub(Money);
// Transformer
// Subtracts value of money object in parameter
private:
int dollars;
int cents;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1120
15. Money::Money()
// Default constructor
// Creates object with value $0.00
{
dollars = 0;
cents = 0;
}
It is easier to choose one name and then vary the one to which it is compared. The letter
in the Reason for Test Case column refers back to the letters above. The name David John
Jones is compared to the input, which is the second name. This is not repeated in the
table. The expected output column does not show the completely documented output,
just the path.
3. #include <iostream>
#include "NameType.h"
int main()
{
NameType name1("David", "John", "Jones");
switch (name1.ComparedTo(name2))
{
DalePhatANS_complete 8/18/04 10:31 AM Page 1122
case BEFORE :
cout << name1w << " comes before "
<< name2w << endl;
break;
case SAME :
cout << name1w << " is the same as "
<< name2w << endl;
break;
case AFTER :
cout << name1w << " comes after "
<< name2w << endl;
}
}
return 0;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1123
4. The initial comes before the same letter in a longer string. The period comes before any
letter in a longer string in that position.
5. Enhance the NameType class with a title field and an observer function to return its
value.
//*****************************************************************
// SPECIFICATION FILE (Name.h)
// This file gives the specification of the Name abstract
// data type. There are two constructors: one takes the first,
// middle, and last name as parameters and the second prompts for
// and reads the name from the standard input device.
//*****************************************************************
#include <iostream>
#include <string>
#include "relType.h"
class Name
{
public:
Name();
// Default constructor
// Postcondition:
// first, middle, last, and title have been set to blanks
void ReadName();
// Postcondition:
// Name is prompted for and read from the standard input
// device
private:
string first; // Person's first name
string last; // Person's last name
string middle; // Person's middle name
string title; // Person's title
};
//*****************************************************************
// IMPLEMENTATION FILE (Name.cpp)
// The file implements the Name member functions.
//*****************************************************************
DalePhatANS_complete 8/18/04 10:31 AM Page 1125
#include "Name.h"
#include <iostream>
//******************************************************************
Name::Name()
// Default constructor
// Postcondition:
// first, middle, and last have been set to blanks
{
first = " ";
middle = " ";
last = " ";
title = " ";
}
//******************************************************************
//******************************************************************
{
first = firstName; // Assign parameters
last = lastName;
middle = middleName;
title = nameTitle;
}
//******************************************************************
void Name::ReadName()
// Postcondition:
// Name prompted for and read from the standard input device
{
cout << "Enter first name: "; // Prompt for first name
cin >> first; // Get first name
cout << "Enter middle name: "; // Prompt for middle name
cin >> middle; // Get middle name
cout << "Enter last name: "; // Prompt for last name
cin >> last; // Get last name
cout << "Enter title: "; // Prompt for title
cin >> title; // Get title
}
//******************************************************************
string Name::FirstName() const
// Postcondition:
// Return value is first
{
return first;
}
//******************************************************************
//******************************************************************
{
return middle;
}
//******************************************************************
//******************************************************************
//******************************************************************
If you add the title to the ComparedTo function, the titles would be compared as strings.
Mr. would come before Mrs. and Dr. would come before Mr. There would be no semantic
sense in such a comparison.
19. ***
DalePhatANS_complete 8/18/04 10:31 AM Page 1129
20. * * *
* *
* * *
* *
* * *
c. struct dayRecord
{
int Day;
string activity;
};
enum DayNames {SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY};
dayRecord Calendar[6][7];
3. DataSet set[3];
4. for (int row = 0; row < 3; row++)
for (int col = 0; col < 5; col++)
set[row][col] = 0.0;
7. struct Size
{
int height;
int width;
};
enum Medium {OIL, WATERCOLOR, PASTEL, ACRYLIC,
PRINT, COLORPHOTO, BWPHOTO};
enum Room {MAIN, GREEN, BLUE, NORTH, SOUTH,
ENTRY, BALCONY};
struct ArtWork
{
string artist;
string title;
Medium medium;
Size size;
Room room;
float price;
}
typedef ArtWork GalleryList[120];
ArtWork currentList;
int numPieces;
8. a. currentList[36]
b. currentList[11].title
c. currentList[84].size.width
d. currentList[119].room
e. currentList[77].artist[0]
DalePhatANS_complete 8/18/04 10:31 AM Page 1131
15. for (Notes note = A; note <= GSHARP; note = Notes(note + 1))
cout << scale[3][note] << endl;
float difference;
}
{
string inFileName;
string outFileName;
string heading;
cout << "Enter the name of the file to be processed" << endl;
cin >> inFileName;
text.open(inFileName.c_str());
cout << "Enter the name of the output file" << endl;
cin >> outFileName;
outFile.open(outFileName.c_str());
cout << "Enter a heading for the output file." << endl;
cin >> heading;
outFile << heading << endl << endl;
}
5. It might be slightly better to have the input of the heading in the function that does the
printing.
6. It has identified the smallest value in the portion of the list that remains to be sorted.
7. a. 20, b. 21, c. 42, d. 22.
8. True.
9. True.
10. 5
11. Because the values in a sorted list are always kept in order.
12. Two iterations. Middle is initially 7, then location 11 (which holds the 12th value)
becomes middle.
13. 'H', 'o', 'p', and '\0'
DalePhatANS_complete 8/18/04 10:31 AM Page 1134
{
if (!IsPresent(item))
{
data[length] = item;
length++;
}
}
3. The List type is only defined to have enough room for 50 items. We must change
MAX_LENGTH in the specification file to be at least 100.
4. void DeleteAll( /* in */ ItemType item);
// Precondition:
// NOT IsEmpty()
// && item is assigned
// Postcondition:
// IF item is present in list
// All occurrences of item are deleted from list
// && Length() ==
// Length()[at]entry – number of occurrences of item
// ELSE
// List is unchanged
{
int index = 0;
while (index < length)
{
if (item == data[index])
{
DalePhatANS_complete 8/18/04 10:31 AM Page 1135
{
int index = 0;
while (index < length && oldItem != data[index])
index++;
if (index < length)
data[index] = newItem;
}
8. The Insert and BinSearch functions must be changed to enable descending order. We
don’t have to change IsPresent or Delete, because they both use BinSearch to locate
the item.
9. The only changes needed to make the binary search work with descending order are to
cause the search area to change to the last half of the current search area when the item
is less than the middle value, and vice versa. These changes are noted with comments in
the following code:
void SortedList::BinSearch(
/* in */ ItemType item,
/* out */ bool& found,
/* out */ int& position ) const
{
int first = 0;
DalePhatANS_complete 8/18/04 10:31 AM Page 1136
found = false;
while (last >= first && !found)
{
middle = (first + last) / 2;
if (item > data[middle]) // Changed < to >
last = middle - 1;
else if (item < data[middle]) // Changed > to <
first = middle + 1;
else
found = true;
}
if (found)
position = middle;
}
{
int first;
int index = 0;
while (index < length && item != data[index])
index++;
first = index;
while (index < length && item == data[index])
index++;
for (int position = index; position < length; position++)
data[first + position - index] = data[position];
length = length – (index – first);
}
11. The simplest way to do this is to use the member functions Delete and Insert. We could
also combine the code from both of these functions into a single function; however, the
savings from that approach would be minimal: We would avoid the decrementing and
incrementing of length, and save the overhead of calling the functions.
void SortedList::Replace( /* in */ ItemType oldItem,
/* in */ ItemType newItem)
{
int oldLength;
oldLength = length;
Delete(oldItem);
if (oldLength > length) // Only insert if oldItem deleted
Insert(newItem);
}
#include <fstream>
DalePhatANS_complete 8/18/04 10:31 AM Page 1138
#include <iostream>
#include <iomanip>
#include "list.h"
// Function Prototypes
int main()
{
List grades; // A list of grades
inData.close();
outData.close();
return 0;
}
//*****************************************************************
{
string inFileName;
string outDataName;
cout << "Enter the name of the file to be processed" << endl;
cin >> inFileName;
text.open(inFileName.c_str());
cout << "Enter the name of the output file" << endl;
cin >> outDataName;
outFile.open(outDataName.c_str());
//******************************************************************
// Grades are input from file inData and inserted into grades.
// Precondition:
// File is not empty
// Postcondition:
// Each grade in the file has been inserted into list of grades
DalePhatANS_complete 8/18/04 10:31 AM Page 1140
{
int grade;
// Read grades and put them into the list
inData >> grade;
while (inData && !grades.IsFull())
{
grades.Insert(grade);
inData >> grade;
}
}
//*****************************************************************
{
int sum = 0;
int limit = grades.Length(); // limit is the number of grades
int grade;
highest = 0;
lowest = 100;
//*****************************************************************
int CalculateAboveAverage
( /* in */ List grades, // List of grades
/* inout */ float average ) // Average grade
{
int roundedAverage = (int) (average + 0.5);
int limit = grades.Length(); // Number of grades
int grade;
int number = 0;
//*****************************************************************
int CalculateBelowAverage
( /* in */ List grades, // List of grades
/* inout */ float average ) // Average grade
{
int truncatedAverage = (int) (average);
int limit = grades.Length(); // Number of grades
int grade;
DalePhatANS_complete 8/18/04 10:31 AM Page 1142
int number = 0;
//*****************************************************************
{
outData << "The number of grades is " << grades.Length()
<< endl;
outData << fixed << setprecision(2) << "The average grade is "
<< average << endl;
outData << "The highest grade is " << highest << endl;
outData << "The lowest grade is " << lowest << endl;
outData << "The number of grades above the average is "
<< aboveAverage << endl;
outData << "The number of grades below the average is "
<< belowAverage << endl;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1143
3. //******************************************************************
// Statistics Program
// This program calculates the average, high score, low score,
// number above the average, and number below the average for
// a file of test scores. The List ADT is used
// Assumption: File "testScores" is not empty and does not contain
// more than MAX_GRADES values.
// To save space, we omit from each function the precondition
// comments that document the assumptions made about valid input
// parameter data. These would be included in a program intended
// for actual use.
// CalculateAboveAverage and CalculateBelowAverage are combined
// into one function.
//******************************************************************
#include <fstream>
#include <iostream>
#include <iomanip>
#include "list.h"
// Function Prototypes
int main()
{
List grades; // A list of grades
ifstream inData;
ofstream outData;
OpenFiles(inData, outData);
if ( !inData // i.outData )
{
cout << "Files did not open successfully"
<< endl;
return 1;
}
// Process grades
InputGrades(grades, inData);
Calculate(grades, average, highest, lowest);
CalculateAboveBelow(grades, average, aboveAverage, belowAverage);
inData.close();
outData.close();
return 0;
}
//*****************************************************************
{
string inFileName;
string outDataName;
cout << "Enter the name of the file to be processed" << endl;
cin >> inFileName;
text.open(inFileName.c_str());
cout << "Enter the name of the output file" << endl;
cin >> outDataName;
DalePhatANS_complete 8/18/04 10:31 AM Page 1145
outFile.open(outDataName.c_str());
//******************************************************************
// Grades are input from file inData and inserted into grades.
// Precondition:
// File is not empty
// Postcondition:
// Each grade in the file has been inserted into list of grades
{
int grade;
// Read grades and put them into the list
inData >> grade;
while (inData && !grades.IsFull())
{
grades.Insert(grade);
inData >> grade;
}
}
//*****************************************************************
{
int sum = 0;
int limit = grades.Length(); // limit is the number of grades
int grade;
DalePhatANS_complete 8/18/04 10:31 AM Page 1146
highest = 0;
lowest = 100;
//*****************************************************************
void CalculateAboveBelow
( /* in */ List grades, // List of grades
/* in */ float average, // Average grade
/* out */ int& aboveAverage,
/* out */ int& belowAverage)
{
int roundedAverage = (int) (average + 0.5);
int truncatedAverage = (int) (average);
int limit = grades.Length(); // Number of grades
int grade;
aboveAverage = 0 ;
belowAverage = 0;
grades.Reset(); // Prepare for iteration
{
grade = grades.GetNextItem();
if (grade > roundedAverage)
aboveAverage++;
if (grade < truncatedAverage)
belowAverage++;
}
//*****************************************************************
int CalculateBelowAverage
( /* in */ List grades, // List of grades
/* inout */ float average ) // Average grade
//*****************************************************************
{
outData << "The number of grades is " << grades.Length()
<< endl;
outData << fixed << setprecision(2) << "The average grade is "
<< average << endl;
outData << "The highest grade is " << highest << endl;
outData << "The lowest grade is " << lowest << endl;
outData << "The number of grades above the average is "
<< aboveAverage << endl;
outData << "The number of grades below the average is "
<< belowAverage << endl;
}
2. #include "testscore.h"
#include <iostream>
#include <string>
TestScore::TestScore(
/* in */ string name,
/* in */ int score)
{
studentName = name;
studentScore = score;
}
IDScore::IDScore(
/* in */ string name,
/* in */ int score,
/* in */ int IDNumber )
: TestScore(name, score)
{
studentIDNumber = IDNumber
}
4. #include "idscore.h"
class Exam
{
public:
SetScore(
/* in */ int location,
/* in */ IDScore score );
IDScore GetScore(
/* in */ int location ) const;
private:
IDScore examList[100];
}
5. #include "exam.h"
Exam::SetScore(
DalePhatANS_complete 8/18/04 10:31 AM Page 1151
/* in */ int location,
/* in */ IDScore score )
{
examList[location] = score;
}
InternPhone::InternPhone(
( /* in */ int newCountry,
/* in */ int newAreaCode,
/* in */ int newNumber,
/* in */ PhoneType newType)
private:
string location;
SimpleDate installDate;
};
11. Computer::Computer(
/* in */ string newName,
/* in */ string newBrand,
/* in */ string newModel,
/* in */ int newSpeed,
/* in */ string newSerial,
/* in */ int newNumber )
{
name = newName;
brand = newBrand;
model = newModel;
DalePhatANS_complete 8/18/04 10:31 AM Page 1153
speed = newSpeed;
serialNumber = newSerial;
inventoryNumber = newNumber;
}
12. InstallRecord::InstallRecord(
/* in */ string newName,
/* in */ string newBrand,
/* in */ string newModel,
/* in */ int newSpeed,
/* in */ string newSerial,
/* in */ int newNumber,
/* in */ string newLocation,
/* in */ SimpleDate newDate )
: Computer( newName, newBrand, newModel,
newSpeed, newSerial, newNumber )
{
location = newLocation;
installDate = newDate;
}
// Postcondition:
// hours, minutes, seconds and time zone have been prompted
// for, read, and set
DalePhatANS_complete 8/18/04 10:31 AM Page 1154
{
string timeZone;
Time::ReadTime();
cout << "Please enter time zone: EST, CST, MST, "
<< "PST, EDT, CDT, MDT, or PDT." << endl;
cin >> timeZone;
if (timeZone == "PST")
zone = EST;
else if (timeZone == "MST")
zone = CST;
else if (timeZone == "PST")
zone = PST;
else if (timeZone = "EDT")
zone = EDT;
else if (timeZone == "CDT")
zone = CDT;
else if (timeZone == "MDT")
zone = MDT;
else
zone = PDT;
}
class AptTime
{
public:
void Set( /* in */ int hours,
/* in */ int minutes );
// Precondition:
// 0 <= hours <= 23 && 0 <= minutes <= 59
// Postcondition:
// hrs == hours && mins == minutes
DalePhatANS_complete 8/18/04 10:31 AM Page 1155
AptTime();
// Postcondition:
// hours and minutes have been set to 0
void ReadTime();
// Postcondition:
// hours and minutes have been prompted for, read,
// and set
private:
int hrs;
int mins;
};
//******************************************************************
// IMPLEMENTATION FILE (AptTime.cpp)
// This file implements the AptTime member functions
//******************************************************************
#include "aptTime.h"
#include <iostream>
DalePhatANS_complete 8/18/04 10:31 AM Page 1156
//******************************************************************
// Precondition:
// 0 <= hours <= 23 && 0 <= minutes <= 59
//
// Postcondition:
// hrs == hours && mins == minutes
{
hrs = hours;
mins = minutes;
}
//******************************************************************
// Precondition:
// The Set function has been invoked at least once
// Postcondition:
// AptTime has been output in the form HH:MM
{
if (hrs < 10)
cout << '0';
cout << hrs << ':';
if (mins < 10)
cout << '0';
cout << mins;
}
//******************************************************************
// Precondition:
// The Set function has been invoked at least once
// for both this AptTime and otherAptTime
DalePhatANS_complete 8/18/04 10:31 AM Page 1157
// Postcondition:
// Function value == true, if this AptTime equals otherAptTime
// == false, otherwise
{
return (hrs == otherAptTime.hrs && mins == otherAptTime.mins);
}
//******************************************************************
//******************************************************************
int AptTime::Hours() const
// Postcondition:
// Return value is hrs
{
return hrs;
}
//******************************************************************
//******************************************************************
DalePhatANS_complete 8/18/04 10:31 AM Page 1158
void AptTime::ReadTime()
// Postcondition:
// hours, minutes, and seconds have been prompted for, read,
// and stored into hrs and mins
{
cout << "Enter hours (<= 23): " << endl;
cin >> hrs;
cout << "Enter minutes (<= 59): " << endl;
cin >> mins;
}
//******************************************************************
AptTime::AptTime()
// Default constructor
// Postcondition
// hrs and mins have been set to 0
{
hrs = 0;
mins = 0;
}
//******************************************************************
2. Yes, it would be appropriate for active time to inherit from static time, because active
time is static time and more.
3. Here are the necessary changes.
• An enumerated type consisting of AM and PM would have to be defined.
• The constructors and the Set operation would have to include the AM/PM field.
• The Equal and LessThan operations would have to include AM/PM in the tests.
DalePhatANS_complete 8/18/04 10:31 AM Page 1159
4. //******************************************************************
// SPECIFICATION FILE (AptTime.h)
// This file gives the specification of an AptTime ADT with
// action responsibilities and knowledge responsibilities.
// A field for AM/PM is included.
//******************************************************************
class AptTimeEx
{
public:
void Set( /* in */ int hours,
/* in */ int minutes,
/* in */ AmPm amOrPm );
// Precondition:
// 0 <= hours <= 23 && 0 <= minutes <= 59
// Postcondition:
// hrs == hours && mins == minutes
// && timeOfDay == amOrPm
// Precondition:
// 0 <= initHrs <= 23 AND 0 <= initMins <= 59
// Postcondition:
// Class object is constructed
// AND Time is set according to the incoming parameters
AptTimeEx();
// Postcondition:
// hours and minutes have been set to 0 AM
void ReadTime();
// Postcondition:
// hours, minutes, and AM or PM have been prompted
// for, read, and set
private:
int hrs;
int mins;
AmPm timeOfDay;
};
//******************************************************************
// IMPLEMENTATION FILE (AptTimeEx.cpp)
// This file implements the AptTimeEx member functions
//******************************************************************
#include "aptTimeEx.h"
#include <iostream>
//******************************************************************
// Precondition:
// 0 <= hours <= 23 && 0 <= minutes <= 59
//
// Postcondition:
// hrs == hours && mins == minutes
DalePhatANS_complete 8/18/04 10:31 AM Page 1161
{
hrs = hours;
mins = minutes;
timeOfDay = amOrPm;
}
//******************************************************************
// Precondition:
// The Set function has been invoked at least once
// Postcondition:
// AptTimeEx has been output in the form HH:MM:SS
{
if (hrs < 10)
cout << '0';
cout << hrs << ':';
if (mins < 10)
cout << '0';
cout << mins;
if (timeOfDay == AM)
cout << " AM";
else
cout << " PM";
}
//******************************************************************
// Precondition:
// The Set function has been invoked at least once
// for both this AptTimeEx and otherAptTimeEx
// Postcondition:
// Function value == true, if AptTimeEx equalsotherAptTimeEx
// == false, otherwise
{
return (hrs == otherAptTimeEx.hrs && mins == otherAptTimeEx.mins
&& otherAptTimeEx.timeOfDay == timeOfDay);
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1162
//******************************************************************
//******************************************************************
//******************************************************************
{
return timeOfDay;
}
//******************************************************************
void AptTimeEx::ReadTime()
// Postcondition:
// hours, minutes, and seconds have been prompted for, read,
// and stored into hrs and mins
{
string dayNight;
cout << "Enter hours (<= 23): " << endl;
cin >> hrs;
cout << "Enter minutes (<= 59): " << endl;
cin >> mins;
cout << "Enter AM or PM" << endl;
cin >> dayNight;
if (toupper(dayNight[0]) == 'A')
timeOfDay = AM;
else
timeOfDay = PM;
}
//******************************************************************
AptTimeEx::AptTimeEx()
// Default constructor
// Postcondition
// hrs and mins have been set to 0 and timeOfDay to AM
{
hrs = 0;
mins = 0;
timeOfDay = AM;
}
//******************************************************************
{
hrs = hours;
mins = minutes;
timeOfDay = amOrPm;
}
5. #include <iostream>
#include "AptTimeEx.h"
int main()
{
AptTimeEx time1(8, 30, AM);
AptTimeEx time2;
time1.Write();
cout << endl;
time2.Write();
cout << endl;
for (int count = 1; count < 4; count++)
{
time2.ReadTime();
if (time1.LessThan(time2))
{
time1.Write();
cout << " is less than ";
time2.Write();
cout << endl;
}
else
{
time1.Write();
cout << " is not less than ";
time2.Write();
cout << endl;
}
if (time1.Equal(time2))
{
time1.Write();
cout << " is equal to ";
time2.Write();
cout << endl;
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1165
else
{
time1.Write();
cout << " is not equal to ";
time2.Write();
cout << endl;
}
}
return 0;
}
2. char* charArrPointer;
char[4] initials;
charArrPointer = initials;
charArrPointer[1] = 'A';
charArrPointer[2] = 'E';
charArrPointer[3] = 'W';
3. struct Phone
{
int country;
int area;
int number;
}
Phone newPhone;
Phone* structPointer;
structPointer = &newPhone;
structPointer->country = 1;
structPointer->area = 888;
structPointer->number = 5551212;
4. struct Phone
{
int country;
int area;
int number;
}
Phone newPhone;
Phone& structReference = newPhone;
structReference.country = 1;
structReference.area = 888;
structReference.number = 5551212;
5. bool ShallowCompare
( /* in */ structPointer first,
/* in */ structPointer second )
{
return (first == second);
}
6. bool DeepCompare
( /* in */ structPointer first,
/* in */ structPointer second )
{
return (first->country == second->country &&
first->area == second->area &&
first->number == second->number);
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1167
8. int Greatest(
( /* inout */ int data[],
/* in */ int size )
{
static max = data[0];
for(int index = 1; index < size; index++)
if (data[index] > max)
max = data[index];
delete [] data;
return max;
}
9. int GetGreatestInput()
{
int size;
int* values;
cout << "Enter number of data values: ";
cin >> size;
values = new int[size];
for(int index = 0; index < size; index++)
{
cout << "Enter integer value: ";
cin >> values[index];
}
return Greatest(values, size);
}
10. ~Circuit()
{
delete [] source;
delete [] sink;
}
int main()
{
int month;
int day;
int year;
Date date1;
date1.Set(10, 30, 2000);
cout << "date1 is " << date1.Month() << "/" << date1.Day()
<< "/" << date1.Year() << endl;
Date date2;
for (int count = 1; count <= 7; count++)
DalePhatANS_complete 8/18/04 10:31 AM Page 1169
{
cout << "Enter month" << endl;
cin >> month;
cout << "Enter day" << endl;
cin >> day;
cout << "Enter year" << endl;
cin >> year;
date2.Set(month, day, year);
switch (date1.ComparedTo(date2))
{
case BEFORE : cout << "date1 comes before date2" << endl;
break;
case SAME : cout << "date1 is the same as date2"
<< endl;
break;
case AFTER : cout << "date1 comes after date2" << endl;
}
}
return 0;
}
2. Copy constructors are needed when initializing a variable in a declaration, when passing
a variable as a value parameter, and when returning the variable as the value of a func-
tion. None of these cases occurs in the problem for which the SortedList class was
implemented; thus, no copy constructor was needed. A destructor is implicitly invoked
when the class object is destroyed. In the problem for which we used the SortedList
class, the objects were declared in the main function; thus, a destructor would not have
been called, and was thus unnecessary.
However, it would be safer and better style to include these functions because you
can never tell how a user might use objects of this class in their programs.
3. Recall that a top-down design produces a hierarchy of tasks, and an object-oriented
design produces a hierarchy of objects. Clearly the process used to build the appointment
calendar demonstrated object-oriented design.
4. The next step is to put all the pieces together to form a collection of days ordered by
date. The Case Studies in Chapters 12 and 13 demonstrated two different ways to imple-
ment a collection: using the data itself as an index and keeping a list of the data. Thus,
the collection of days can be implemented as follows:
• A list of days
• A one-dimensional array in which the month is used as an index into a list of days for
the month
• A two-dimensional array in which the month is one index and the day is the other
index and each cell contains the appointments for one day
DalePhatANS_complete 8/18/04 10:31 AM Page 1170
6. NodePtr savePtr;
savePtr = head;
head = currPtr->link;
head->link = savePtr;
currPtr->link = currPtr->link->link;
7. auxPtr = currPtr;
while (auxPtr->link != NULL)
auxPtr= currPtr->link;
auxPtr->NULL;
8. auxPtr = currPtr;
if (auxPtr != NULL)
if (auxPtr->link == NULL)
auxPtr = NULL;
else
{
while (auxPtr->link != NULL)
auxPtr= currPtr->link;
auxPtr->NULL;
}
smallPtr = head;
tailPtr = NULL;
smallTrailing = NULL;
while (tempPtr != NULL) // find smallest
{
if (smallPtr->component > tempPtr->component)
{
smallPtr = tempPtr;
smallTrailing = tailPtr;
}
tailPtr = tempPtr;
tempPtr = tempPtr->link;
}
// remove node
if (smallTrailing == NULL) // only one node left
head = smallPtr -> link; // set end of loop
else
smallTrailing->link = smallPtr->link; // remove node
}
head = headS;
currPtr = headS;
}
NodePtr newNode;
NodePtr tempPtr = head; // used for traversal
DalePhatANS_complete 8/18/04 10:31 AM Page 1173
newNode->link = headR;
headR = newNode;
tempPtr = tempPtr->link
}
}
// Postcondition:
// If list is full, EntryListIsfull exception is thrown; if
// time is already filled, DuplicateTime exception is thrown;
// else newEntry is inserted in list
{
if (list.IsFull())
throw EntryListIsFull();
else
if (list.IsPresent(newEntry))
throw DuplicateTime();
else
list.Insert(newEntry);
}
3. #include "Name.h"
// ShortName specification
class ShortName : public Name
{
public:
void ReadName();
ShortName(/* in */ string firstName,
/* in */ string middleName,
/* in */ string lastName);
ShortName();
string FirstName() const;
// Postcondition:
// Return value is this person's first name
DalePhatANS_complete 8/18/04 10:31 AM Page 1174
private:
string first;
string last;
};
#include "ShortName.h"
// ShortName implementation
void ShortName::ReadName()
// Postcondition:
// Name prompted for and read from the standard
// input device
{
cout << "Enter first and last names "
<< "separated by a blank." << endl;
cin >> first >> last;
Name:SetName(first, " ", last);
}
ShortName::ShortName()
{
// Postcondition:
// Return value is this person's last name
{
return Name::LastName();
}
4. void AptTime::ReadTime()
// Postcondition:
// hours, minutes, and seconds have been prompted for, read,
// and stored into hrs and mins
{
cout << "Enter hours (<= 23)and minutes (<=59) "
<< "separated by a blank" << endl;
cin >> hrs >> mins;
}
5. This is a matter of taste, but most of you will prefer the shorter entry.
6. There are several ways to look at this question. If we knew for sure that the calendar only
contained appointments for one year, then it probably would be more efficient to just
check the day; however, there is nothing in the program that assumes that only one year
is represented. As it stands now, the calendar can represent any number of years. Thus,
using the date comparison takes care of both situations.
11. a. Control would continue with the statements following the entire Try-catch statement.
Almost certainly, this would be wrong. For example, the final comments indicate
“close the output file,” but the output file has already been closed in the Catch clause.
b. If we change throw to return, the calling code won’t have any idea that a BadData
exception occurred. This may or may not be wrong, depending on the design of the
program.
12. In the Catch clause, insert return 1; after the output statement.
13. The exception passes to the function that called the function containing the call. If that
one also doesn’t have a handler for the exception, the process repeats with the next
higher caller. If the exception reaches main without finding a handler, it is uncaught; an
error message is then output, and the program terminates abnormally.
14. It rethrows the exception.
15. bad_alloc
2. PrintSquare<int>(10);
PrintSquare<long>(10L);
PrintSquare<float>(10.0);
or
PrintSquare(10);
PrintSquare(10L);
PrintSquare(10.0);
3. template<>
void PrintSquare(string value)
{
cout << value << value;
}
b. cout << Twice(someInt) << ' ' << Twice(someFloat) << endl;
DalePhatANS_complete 8/18/04 10:31 AM Page 1177
5. template<class NumType>
NumType Sum( NumType arr[], int size )
{
int i; // Index variable
NumType sum = 0; // Sum of the elements
6. template<class SomeType>
void GetData( string promptStr, SomeType& data )
{
cout << promptStr << ' ';
cin >> data;
}
7. template<>
void GetData( string promptStr, AutoType& data )
{
char ch; // The input character
8. a. GList<int> intList;
GList<float> floatList;
b. i = 10;
while (i <= 80 && !intList.IsEmpty())
{
// Below, use "while", not "if", because
// duplicates are allowed in a list
DalePhatANS_complete 8/18/04 10:31 AM Page 1178
while (intList.IsPresent(i))
{
intList.Delete(i);
floatList.Insert(0.5 * float(i));
}
i++;
}
15. try
{
cout << Sum(oneInt, anotherInt) << endl;
}
catch ( SumTooLarge )
{
cout << "*** Error: Sum is too large" << endl;
throw;
}
// Postcondition:
// The user has been prompted for a file name
// && IF the file could not be opened
// An error message has been printed
// && An OpenFailed exception has been thrown
{
string fileName; // User-specified file name
someFile.open(fileName.c_str());
if ( !someFile )
{
cout << "** Can't open " << fileName << " **" << endl;
throw OpenFailed();
}
}
b. Note that the calling code below does not print an error message. The error message
has already been printed by OpenForInput, as advertised by its postcondition.
ifstream inFile;
try
{
OpenForInput(inFile);
}
catch ( OpenFailed )
{
return 1;
}
// Success keep executing
// Precondition:
// This and input parameter contains valid times
// Postcondition:
// Return value is
// BEFORE, if this time comes before otherTime
// SAME, if this time and otherTime are the same
// AFTER, if this time comes after otherTime
AptTime();
// Postcondition:
// hours and minutes have been set to 0
void ReadTime();
// Postcondition:
// hours and minutes have been prompted for, read,
// and set
private:
int hrs;
int mins;
};
#endif
//******************************************************************
// IMPLEMENTATION FILE (AptTime.cpp)
// This file implements the AptTime member functions
//******************************************************************
#include "aptTimeEx.h"
#include <iostream>
DalePhatANS_complete 8/18/04 10:31 AM Page 1183
//******************************************************************
// Precondition:
// 0 <= hours <= 23 && 0 <= minutes <= 59
//
// Postcondition:
// hrs == hours && mins == minutes
{
hrs = hours;
mins = minutes;
}
//******************************************************************
// Postcondition:
// AptTime has been output in the form HH:MM
{
if (hrs < 10)
cout << '0';
cout << hrs << ':';
if (mins < 10)
cout << '0';
cout << mins;
}
//******************************************************************
// Precondition:
// This and input parameter contains valid times
// Postcondition:
// Return value is
// BEFORE, if this time comes before otherTime
// SAME, if this time and otherTime are the same
// AFTER, if this time comes after otherTime
DalePhatANS_complete 8/18/04 10:31 AM Page 1184
{
if (hrs == otherAptTime.hrs && mins == otherAptTime.mins)
return SAME;
else
if (hrs < otherAptTime.hrs ||
hrs == otherAptTime.hrs && mins < otherAptTime.mins)
return BEFORE;
}
//******************************************************************
//******************************************************************
//******************************************************************
void AptTime::ReadTime()
// Postcondition:
// hours, minutes, and seconds have been prompted for, read,
// and stored into hrs and mins
{
cout << "Enter hours (<= 23): " << endl;
cin >> hrs;
cout << "Enter minutes (<= 59): " << endl;
cin >> mins;
}
//******************************************************************
AptTime::AptTime()
// Default constructor
// Postcondition
// hrs and mins have been set to 0
DalePhatANS_complete 8/18/04 10:31 AM Page 1185
{
hrs = 0;
mins = 0;
}
//******************************************************************
//*****************************************************************
// SPECIFICATION FILE (Entry.h)
// This file contains the specification of the Entry ADT,
// which has two contained classes, Name and AptTime
//*****************************************************************
#ifndef ENTRY
#define ENTRY
#include "AptTimeEx.h"
#include "Name.h"
#include <string>
#include "relType.h"
class Entry
{
public:
string NameStr() const;
// Returns a string made up of first name, blank, last name
// Postcondition:
// Return value is first name of Name object, blank, and
// last name of Name object
// Postcondition:
// Return value is hours from Time object, colon, and
// minutes of Time object
Entry();
// Default constructor
// Postcondition:
// Entry object has been constructed
void ReadEntry();
// Postcondition:
// Name and time have been prompted for and read
private:
Name name;
AptTime time;
};
#endif
//*****************************************************************
// IMPLEMENTATION FILE (Entry.cpp)
// This file contains the specification of the Entry ADT,
// which has two contained classes, Name and Time
//*****************************************************************
DalePhatANS_complete 8/18/04 10:31 AM Page 1187
#include "EntryEx.h"
#include <string>
#include <fstream>
#include <iostream>
{
return (name.FirstName() + ' ' + name.LastName());
}
{
ifstream tempIn;
ofstream tempOut;
tempOut.open("convert");
tempOut << time.Hours() << ":" << time.Minutes() << endl;
tempOut.close();
tempIn.open("convert");
string temp;
tempIn >> temp;
tempIn.close();
return temp;
}
void Entry::ReadEntry()
// Postcondition:
// Values have been read from the keyboard into name and time.
DalePhatANS_complete 8/18/04 10:31 AM Page 1188
{
name.ReadName();
time.ReadTime();
}
Entry::Entry()
// Default constructor
// Postcondition:
// Entry object has been constructed
{
}
// Parameterized constructor
// Postcondition:
// Entry object has been constructed with firstName,
// middleName, and lastName as arguments to Name
// parameterized constructor; initHours, initMinutes,
// and initSeconds as arguments to Time parameterized
// constructor
{
}
// SPECIFICATION FILE (SortedList2.h)
// This file gives the specification of a sorted list abstract data
// type. The list items are maintained in ascending order of
// value
//******************************************************************
DalePhatANS_complete 8/18/04 10:31 AM Page 1189
template<class ItemType>
// Forward declaration
template<class ItemType>
class SortedList2
{
public:
bool IsEmpty() const;
// Postcondition:
// Return value is true if list is empty;
// false otherwise
// Postcondition:
// Return value is true if list is full;
// false otherwise
// Precondition:
// item is assigned
// Postcondition:
// item is in list
// && List components are in ascending order
// Precondition:
// item is somewhere in list
// Postcondition:
// First occurrence of item is no longer in list
// && List components are in ascending order
void Reset();
// Postcondition:
// Iteration is initialized
ItemType GetNextItem();
// Precondition:
// No transformers have been invoked since last call
DalePhatANS_complete 8/18/04 10:31 AM Page 1190
// Postcondition:
// Returns component at the current position
// in the SortedList
int Length();
// Postcondition:
// Return value is length of list
SortedList2();
// Constructor
// Postcondition:
// Empty list is created
SortedList2(int maxLength);
// Constructor
// Postcondition:
// Empty list is created
// Copy-constructor
// Postcondition:
// List is created as a duplicate of otherList
~SortedList2();
// Destructor
// Postcondition:
// List is destroyed
private:
NodeType<ItemType>* head;
NodeType<ItemType>* currentPos;
int length;
int maxSize;
};
DalePhatANS_complete 8/18/04 10:31 AM Page 1191
#include "SortedList2.cpp"
//******************************************************************
// IMPLEMENTATION FILE (SortedList.cpp)
// This file implements the SortedList2 class member functions
// List representation: a linked list of dynamic nodes
//******************************************************************
#include <iostream>
#include <cstddef> // For NULL
#include "relType.h"
using namespace std;
template<class ItemType>
struct NodeType
{
ItemType item;
NodeType<ItemType>* link;
};
//******************************************************************
template<class ItemType>
SortedList2<ItemType>::SortedList2()
// Constructor
// Postcondition:
// head == NULL AND maxSize set to 1000
{
head = NULL;
length = 0;
maxSize = 1000;
}
//******************************************************************
template<class ItemType>
SortedList2<ItemType>::SortedList2(int maxLength)
DalePhatANS_complete 8/18/04 10:31 AM Page 1192
// Constructor
// Postcondition:
// head == NULL
{
head = NULL;
length = 0;
maxSize = maxLength;
}
//******************************************************************
template<class ItemType>
SortedList2<ItemType>::SortedList2( const SortedList2<ItemType>&
otherList )
// Copy-constructor
// Postcondition:
// IF otherList.head == NULL (i.e., the other list is empty)
// head == NULL
// ELSE
// head points to a new linked list that is a copy of
// the linked list pointed to by otherList.head
{
TNodeType<ItemType>* fromPtr; // Pointer into list being copied
TNodeType<ItemType>* toPtr; // Pointer into list being built
if (otherList.head == NULL)
{
head = NULL;
return;
}
fromPtr = otherList.head;
head = new TNodeType<ItemType>;
head->item = fromPtr->item;
toPtr = head;
fromPtr = fromPtr->link;
DalePhatANS_complete 8/18/04 10:31 AM Page 1193
//******************************************************************
template<class ItemType>
SortedList2<ItemType>::~SortedList2()
// Destructor
// Postcondition:
// All linked list nodes have been deallocated from free store
{
TNodeType<ItemType>* temp; // Temporary variable
while ( !IsEmpty() )
{
temp = head;
head = head->link;
delete temp;
}
}
//******************************************************************
template<class ItemType>
bool SortedList2<ItemType>::IsEmpty() const
// Postcondition:
// Return value is true if head == NULL; false otherwise
{
return (head == NULL);
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1194
//****************************************************************
template<class ItemType>
bool SortedList2<ItemType>::IsFull() const
// Postcondition:
// Return value is false
{
return length == maxSize;
}
//****************************************************************
template<class ItemType>
void SortedList2<ItemType>::Insert( /* in */ ItemType item )
// Precondition:
// item members of list nodes are in ascending order
// && item is assigned
// Postcondition:
// New node containing item is in its proper place
// in linked list
// && item members of list nodes are in ascending order
{
TNodeType<ItemType>* currentPtr; // Moving pointer
TNodeType<ItemType>* prevPtr; // Trailing pointer
TNodeType<ItemType>* newNodePtr; // Pointer to new node
newNodePtr->link = currentPtr;
if (prevPtr == NULL)
head = newNodePtr;
else
prevPtr->link = newNodePtr;
length++;
}
//******************************************************************
template<class ItemType>
void SortedList2<ItemType>::Delete( /* in */ ItemType item )
// Precondition:
// item members of list nodes are in ascending order
// Postcondition:
// Node containing first occurrence of item is no longer in
// linked list
// && item members of list nodes are in ascending order
{
TNodeType<ItemType>* currentPtr;
TNodeType<ItemType>* prevPtr;
currentPtr = head;
prevPtr = NULL;
if (currentPtr != NULL)
{
prevPtr->link = currentPtr->link;
length--;
}
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1196
template<class ItemType>
void SortedList2<ItemType>::Reset()
// Postcondition:
// Iteration is initialized
{
currentPos = NULL;
}
template<class ItemType>
ItemType SortedList2<ItemType>::GetNextItem()
// Precondition:
// No transformers have been invoked since last call
// Postcondition:
// Returns item at the current position in the SortedList and
// resets current to next position or first position if
// last item is returned
{
ItemType item;
if (currentPos == NULL)
currentPos = head;
item = currentPos->item;
currentPos = currentPos->link;
return item;
}
template<class ItemType>
int SortedList2<ItemType>::Length()
// Postcondition:
// Return value is length
{
return length;
}
template<class ItemType>
bool SortedList2<ItemType>::IsPresent(ItemType item)
{
TNodeType<ItemType>* currentPtr; // Moving pointer
currentPtr = head;
while (currentPtr != NULL
&& currentPtr->item.ComparedTo(item) != SAME)
currentPtr = currentPtr->link;
13. 10
20
30
30
20
10
14. abcc
d
e
15. abcd
e
f
DalePhatANS_complete 8/18/04 10:31 AM Page 1198
4. void Ex4()
{
int number;
cout << "Enter a positive number, 0 to end: ";
cin >> number;
DalePhatANS_complete 8/18/04 10:31 AM Page 1199
if (number != 0)
{
cout << number << endl;
Ex4();
cout << number << endl;
}
}
if (number != 0)
{
cout << "Total: " << sum + number <<endl;
Ex5(sum + number);
cout << number << endl;
}
}
if (number != 0)
{
cout << "Total: " << sum + number <<endl;
Ex6(sum + number, revSum);
revSum = revSum + number;
cout << number << " Total: " << revSum << endl;
}
}
{
Ex7(greatest);
cout << number << endl;
}
}
The greatest must be written immediately following the call.
if (number != 0)
{
cout << "Greatest: " << greatest << endl;
Ex8(greatest);
cout << number << endl;
}
}
The greatest must be written immediately following the call.
9. #include <iostream>
void Ex9(int&);
int main()
{
int sum = 0;
int revSum = 0;
Ex9(revSum);
cout << "The greatest is " << revSum;
return 0;
}
//*******************
{
int number;
int greatestSoFar = 0;
cout << "Enter a positive number, 0 to end: ";
cin >> number;
if (number > 0)
{
Ex9(greatestSoFar);
if (number > greatestSoFar)
greatest = number;
else
greatest = greatestSoFar;
cout << number << " Greatest: " << greatest
<< endl;
}
}
}
}
}
}
DalePhatANS_complete 8/18/04 10:31 AM Page 1202
PtrType tempPtr;
if (head1 != NULL)
{
tempPtr = new NodeType;
tempPtr->info = head1->info;
tempPtr->link = head2;
head2 = tempPtr;
CopyReverse(head1->link, head2);
if (head1 != NULL)
{
tempPtr = new NodeType;
tempPtr->info = head1->info;
tempPtr->link = head2;
head2 = tempPtr;
Copy(head1->link, head2->link);
}
}
}
or