Chapter 14 Projects
Chapter 14 Projects
704 weightInPounds
heightInInches 2
a) Implement a program that prompts the user for height and weight values and displays the
associated body mass index.
Perform input validation by making sure that the user enters positive decimal numbers for height
and weight. See the sample session for details. In particular, note the format for the echo-printed
height and weight values and for the generated body-mass-index value.
For this program, theres no need for multiple classes or even multiple methods. Just put all your
code in a main method and put the main method in a BodyMassIndex class.
Sample session:
Enter height in inches: hi
Invalid inches value. Must be a decimal number.
Re-enter height in inches: 0
Invalid inches value. Must be positive.
Re-enter height in inches: 69.25
Enter weight in pounds: dog
Invalid pounds value. Must be a decimal number.
Re-enter weight in pounds: -3
Invalid pounds value. Must be positive.
Re-enter weight in pounds: 150.5
height = 69.25"
weight = 150.5 pounds
body mass index = 22.1
b) The difference between this program and the previous program is that this program uses feet and
inches for the height value rather than just feet.
Perform input validation by making sure that the user enters a positive integer number for feet, a
nonnegative decimal number for inches, and a positive decimal number for weight. See the
sample session for details. In particular, note the format for the echo-printed height and weight
values and for the generated body-mass-index value.
Sample session:
Enter height using feet space inches (e.g., 5 6.25): hi there
number.
(e.g., 5 6.25): 0 9
(e.g., 5 6.25): 5.25 0
(e.g., 5 6.25): 5 9.25
height = 5'-9.25"
weight = 150.5 pounds
body mass index = 22.1
2. [after 14.5] Storage and Retrieval of Objects in an Array ***:
a) Simple system:
Suppose you want to create a database of objects which can be stored and retrieved by the value
of one of their instance values the key value. Use an instance variable, number, to keep track
of the total number of objects already stored, add each new object at index equal to this total
value, and then increment this total value by one. To find an object whose key value is equal to
some reference value, step through the array sequentially and compare each objects key value
with the reference value.
Heres a UML class diagram describing a program that manages such a system:
SimpleEmployeesDriver
SimpleEmployees
+main(args : String[]) : void
-add(j : int) : void
Employee
-name : String
-ssn : int
-employees : Employee[]
-number : int
+create(maximum : int) : void
+getEmployee(index : int) : Employee
+add(employee : Employee) : int
+findEmployee(ssn : int) : int
+displayAll() : void
Make the SimpleEmployees class define an array of employees and keep number equal to
the number of non-null elements in the array. Fill continuously from zero up to index =
number 1. Have the create method instantiate the array with length equal the maximum
possible number of employees. In the SimpleEmployees.add method, put a reference to the
new employee into the next available spot in the array, increment number, and return number,
which equals the number of steps required to find that element in a sequential search. If number
is already equal to the length of the array, the attempt to add another element throws an
ArrayIndexOutOfBoundsException, so put the dangerous operation in a try block, and
make the catch block print array full and return -1. In the findEmployee method, use a
for loop to perform a sequential search, starting with index = 0. Break when the parameter
value is the same as one of the employees ssn, and return that index value. If no match is
found, return -1.
In the SimpleEmployeesDriver class, provide a helping add method to do the following:
First instantiate an employee whose name is the (j+1) th letter of the alphabet and whose social
security number is a 9-digit integer generated by Math.random. Then call the
SimpleEmployees.add method to try to add that employee to the array. If the attempt to add
to the array is successful, have the SimpleEmployeesDriver.add method print the number
of search steps, the name, and the social security number for that employee.
In the main method, make the array length = 7. Use the above helping add method to add and
display 6 employees, named A through F. Then, display all employee data. Ask user to input
a social security number until the user inputs -1. Then try to add two more employees, G and
H, to demonstrate the exception handling by the try-catch mechanism in the
SimpleEmployees class.
Write the program so that it generates output like the following, recognizing, of course, that the
random 9-digit social security numbers will be different each time you run the program.
Sample session:
search
search
search
search
search
search
A
B
C
D
E
F
steps
steps
steps
steps
steps
steps
=
=
=
=
=
=
1
2
3
4
5
6
A
B
C
D
E
F
298842294
648282605
726358594
280199748
566266888
690250539
298842294
648282605
726358594
280199748
566266888
690250539
335672069
b) Hashing system:
Although the above system is simple, it has a performance problem. The average time to perform
a search is approximately half of the number of items in the array, and it increases as the array
gets longer. It would be nice if you could use the key value as an index. Unfortunately, key values
are often clustered. To distribute the data fairly evenly, you can transform the key value by
hashing it, like this:
hashValue = keyValue % arrayLength;
Then, use the hash value as the index.
This doesnt work perfectly, though. If array length is less than the largest value, sometimes
theres a collision two or more elements have the same hash value. To deal with collisions, use
the hash value as a sequential-search starting point. That is, when adding to the array, first try to
put the element at index = hash value. If thats occupied, try the next higher index value, and
so on wrapping around to index = 0 when you reach the end of the array. If you get back to
the starting point before finding an empty slot, do not add the new element, and print array full.
When retrieving, start the search at index = hash value.
The trick to using a hashing system is to make sure the array is never more than about half full.
As long as your array is less than about half full, on average youll be able to store and retrieve
with no more than about two search steps. If the array has 1000 elements, thats much better than
using an ordinary sequential search, because 2 << 250, where 250 is the average number of pure
sequential search steps for a half-full 1000-element array.
For this part of the project, change the program written for part a so that it implements the
hashing algorithm just described. Use the same Employee class. Change the name
SimpleEmployees to Employees and change the name SimpleEmployeesDriver to
EmployeesDriver. Make the new driver the same except refer to the Employees class
instead of the SimpleEmployees class.
In the Employees class, remove the number instance variable. In the add and
findEmployee methods start by setting index equal to the hash value, as computed above.
Then, starting at this index value, step through the array. When index equals the array length,
wrap around to index = 0, and continue up to the starting point. In the add method, insert the
new element at the first null and then break. Eliminate the try-catch mechanism used in
part a, and use an if clause instead. In the findEmployee method, keep going until a match is
found and break there. In either method, if index gets back to the starting point, return -1.
Since the elements will be scattered around in the array, make the displayAll method traverse
the entire array and print null wherever an array element is unoccupied.
To show the hash value for each element, insert an extra System.out.print statement just
before the loop in the Employees.add method.
Sample session:
hash
hash
hash
hash
hash
hash
F
null
C
D
A
B
E
value
value
value
value
value
value
=
=
=
=
=
=
4
4
2
2
5
0
search
search
search
search
search
search
steps
steps
steps
steps
steps
steps
=
=
=
=
=
=
1
2
1
2
2
1
A
B
C
D
E
F
127902828
622927274
929423679
461102721
009085179
074558470
830485830
074558470
929423679
461102721
127902828
622927274
009085179
Include a method for printing the date with a numeric format. Use the zero-pad flag in a printf
method call to get exactly two digits for each month and day.
Include a method for printing the date with an alphabetic format.
Include a getError method which returns the value of the error instance variable.
5/2
05/02
52
5.0/2
13/2
2/x
2/30
2/28
q
c: readChar()
reads a single (c)haracter
d: readDouble() reads a (d)ouble number
f: readFloat()
reads a (f)loat number
i: readInt()
reads an (i)nt number
l: readLong()
reads a (l)ong number
q: quit
Enter t, c, d, f, i, l, or q: l
Enter a long number: -16
long number = -16
Select one of these options:
t: readLine()
reads a line of (t)ext
c: readChar()
reads a single (c)haracter
d: readDouble() reads a (d)ouble number
f: readFloat()
reads a (f)loat number
i: readInt()
reads an (i)nt number
l: readLong()
reads a (l)ong number
q: quit
Enter t, c, d, f, i, l, or q: q
For the readChar method, if the user simply hits the Enter key, return the \n character. If the user
enters any other single visible or invisible character, return that character. Otherwise, print the error
message:
Invalid entry - expecting a single character.\n
Then terminate the program.
For the readDouble and readFloat methods, if the trimmed input string cannot be parsed, print
the error message:
Invalid entry - expecting a double.\n
or:
Invalid entry - expecting a float.\n
Then terminate the program.
For the readLong and readInt methods, if the trimmed input string cannot be parsed, print the
error message:
Invalid entry - expecting a long.\n
or:
Invalid entry - expecting an int.\n
Then terminate the program.