 |
Loop patterns
|
-
Loops are a common feature in many programs
-
We have seen some patterns for loops performing common operations
-
These patterns are useful, because they occur again and again, and can
be applied in a variety of situations.
Enumerating all elements in a collection with a certain property
Example
-
Display all the employees who have earned more than $500 this week
-
Find all houses for sale for less than $150,000
-
Find all the courses taught by a certain professor
Informal procedure
-
For "collection," assume that we mean "Vector"
-
To enumerate all the elements in a Vector we need an enumeration class
-
We go through the Enumeration object, comparing each element with the property
we desire, and process those only
Choosing and defining variables
-
We need a variable to refer to the Enumeration, and one to compare to the
current element
Enumeration enum;
House house;
Skeleton of the code
public void findHouse (int highestPrice) {
Enumeration enum;
House house;
while (condition) {
body
}
}
The while condition
-
The task is complete when there are no more houses left to compare, so
we continue while the enumeration has more elements
while (enum.hasMoreElements ()) {
body
}
Initialization
-
Because enum is first used in the while condition, it needs to be initialized
enum = theHouses.elements (); // Assume theHouses is a Vector, declared elsewhere
Guaranteeing termination
-
Termination only comes when all elements have been processed
-
We need to make sure that each time through the loop, another element of
the enumeration is processed
while (enum.hasMoreElements ()) {
...
enum.nextElement ();
...
}
Completing the loop body
-
Of course, the nextElement is a house, so it would make sense to assign
it to that variable
-
Also, notice that while we are assigning the variable, currently we are
not processing the element
-
To process the element, we need to check that it has the desired quality
(in our example, that its price is less than $150,000). This implies an
if statement.
void findHouses (int highestPrice) {
Enumeration enum;
House house;
enum = theHouses.elements ();
while (enum.hasMoreElements ()) {
house = (House) enum.nextElement ();
if (house.getPrice () < highestPrice) {
house.print ();
}
}
}
The following pattern "template" can be used whenever a problem like this
occurs (and the elements are in a collection)
void aMethod (...property to check...) {
Enumeration enum;
aClass object;
enum = aCollection.elements ();
while (enum.hasMoreElements ()) {
object = (aClass) enum.nextElement ();
if (..object has property..) {
do something to the object
}
}
Another loop patter: A counter
-
a counter pattern is used when you want to count the number of elements
that have a certain property
-
We need to maintain a counter that counts the number of elements with that
property so far
int count = 0; int count = 0;
// before the loop starts, // before the loop starts,
// we have encountered nothing so far // ...
Enumeration enum; Enumeration enum;
aClass object; House house;
enum = aCollection.elements (); enum = theHouses.elements ();
while (enum.hasMoreElements ()) { while (enum.hasMoreElements ()) {
object = (aClass) enum.nextElement (); house = (House)enum.nextElement ();
if (...object has property...) { if (house.getPrice () < 150000) {
count += 1; count += 1;
} }
} }
Sometimes, it may be desirable to stop the loop when a certain number of
elements has been encountered
For example, we only want to display the first 10 employees that earn more
than $500
int count = 0; int count = 0;
Enumeration enum; Enumeration enum;
aClass object; Employee emp;
enum = aCollection.elements (); enum = employees.elements ()
while (enum.hasMoreElements () && while (enum.hasMoreElements () &&
count != desiredValue) { count != 10) {
object = (aClass) enum.nextElement (); emp = (Employee)enum.nextElement ();
if (...object has property...) { if (emp.calcPay () > 500) {
count += 1; count += 1;
} }
} }
Exercises:
-
Print all courses between 100 and 199 inclusive.
-
Adapt the pattern to work for BasicDataReaders
-
write a loop that reads in lines and counts the number of lines that contain
more than 10 characters
An accumulator
-
Another pattern is useful for applying operations to a group of elements
-
Calculate the sum of the numbers read in from a keyboard
-
Compute the product of n doubles
-
Concatenate all the strings in a vector
SomeType accumulator;
accumulator = some initial value
while (...) {
...
accumulator = some operation
...
}
SomeType accumulator; SomeType accumulator;
Enumeration enum; BasicDataReader in;
aClass object; aType object;
accumulator = initial value; accumulator = initial value;
enum = aCollection.elements (); in = new BasicDataReader (...);
while (enum.hasMoreLements ()) { while (!in.eof ()) {
object = (aClass)enum.nextElement(); object = in.readSomething ();
accumulator = some operation; accumulator = some operation;
} }
Finding extremes
-
In some cases, we may want to find the object/value that is the highest/lowest/longest
-
Find the student with the maximum grade
-
Find the smallest number
-
Find the longest line in a file
-
To do this, we need to keep track of the current object that has the extremest
found so far
Student highest;
Enumeration enum;
Student current;
enum = cpsc101.elements ();
highest = enum.nextElement ();
while (enum.hasMoreElements ()) {
current = (Student)enum.nextElement ();
if (current.mark () > highest.mark ()) {
highest = current;
}
}
This gives the following pattern
SomeType extreme;
Enumeration enum;
SomeType current;
enum = aCollection.elements ();
extreme = enum.nextElement (); // The first element will be the highest
while (enum.hasMoreElements ()) {
current = (SomeType)enum.nextElement ();
if (current is extremer than extreme) {
extreme = current;
}
}
Exercises:
-
Adapt the above pattern to work for files.
-
Write some code that will find the longest line in a file.
-
Last modified: 3/29/99