II. Algorithmic Patterns
(Java Version)
Algorithmic Pattern Index
| Pattern Title |
Purpose |
Pattern
A1 The Basic Input Pattern |
To ask a user to enter a value and store that value in a
variable |
Pattern
A2 Handling Options |
To easily branch to the code corresponding to a choice entered by a
user |
Pattern
B1 The Basic While Loop |
To loop through a set of instructions until some ending or stopping
condition is met. |
Pattern
B2 The While Loop with Priming Read
|
To loop through a set of instructions until the user enters some
sentinel value. |
Pattern
B3 Loop Until Valid Data Entered
|
To loop through a set of instructions until the user enters a 'valid'
value. (This pattern is most often used to force a user to enter one of a
set of correct or acceptable values.) |
Pattern
B4 Loop Until User Confirms Choice to Quit |
To loop through a set of instructions until the user signals and
confirms that he or she is ready to quit |
Pattern
C1 The Basic For Loop
|
To loop through a set of instructions a certain number of times.
|
Pattern
C2 The For Loop with Priming Read
|
To loop through a set of instructions until the user enters some
sentinel value |
Pattern
D1 The Counter Pattern Using a Loop
|
To count the number of times a loop repeats; to implement a counter
|
Pattern
D2 The Sum Pattern Using a Loop |
To calculate the sum of some set of numbers |
Pattern
D3 The Average Pattern |
To calculate the average of some set of numbers |
Pattern
E1 Finding the Largest or Smallest
|
To find the largest or smallest number in a list entered by a user
|
Pattern
E2 Handling Options |
To continuously cause a program to branch to the appropriate code for
each option in a set of user entered options |
Pattern
E3 A General Prompt Producer
|
To allow one function to produce different outputs - in the form of
messages or prompts or whatever |
Pattern
F1 Performing an Action on Each Element of an Array |
To work with or perform some action on all the elements of an array
|
Pattern
F2 Searching an Array |
To search for some value in an array |
Pattern
G1 Opening Files for Input |
To open a file for input |
This document consists of a number of templates or programming patterns
representing general solutions to common algorithm problems. Smart programmers
always break a programming task into some number of subtasks or modules. The
patterns presented here should be used in the coding of those modules.
Once you have determined the purpose of a module, you should go through the
patterns or the pattern index comparing the purpose statement of the patterns
with the purpose statement of the module. You should then write the module using
the appropriate pattern or patterns as a guide. Be aware that although the Java
language is used here to demonstrate these patterns, the patterns themselves are
general to any programming language. For example, these patterns are just as
applicable to Basic, Pascal or C. In certain cases, they are even applicable
to the higher level programming tools often used to avoid the details of
traditional programming.
Be sure to check that all the elements of the appropriate patterns
appear in your module - one of the advantages in using the patterns is to make
sure that you include all the necessary code to accomplish a given purpose. And,
be sure to trace/test your module. The use of patterns and the other tricks of
the programming trade help avoid errors but nothing takes the place of thorough
testing.
Hints on reading these patterns:
- An underlined set of words represents some user declared identifier such
as a variable.
- Examples that represent actual Java code are in bold.
- If you are unclear of the meaning of certain terms in the pattern
discussion or wonder if it might be possible to modify a pattern in a certain
way, be sure to read the information that precedes each pattern section, the
discussion of each pattern and the notes that follow most patterns. However,
after you are familiar with a certain pattern, the only important aspects will
the pattern itself and the example(s). For more discussion of the idea of
patterns as used here, read Chapter 3, Section III of "The Story of C++."
A. Basic Patterns
These are the simplest of patterns. They almost never stand by themselves but
exist as part of other patterns.
Pattern A1: The Basic Input Pattern
Purpose: To ask a user to enter a value and store that value in a
variable
The Pattern: Display 1 or more lines as a prompt to the user
input = get input from user
Example: String s = JOptionPane.ShowInputDialog
("Please enter the pennies deposited.");
int pennies = Integer.parseInt(s);
Discussion: Please remember to ALWAYS include a message (called
a prompt), describing what is to be input, with every
request for data from a user. This message can take many
forms including a simply request as in "Please enter the
pennies deposited" or it can be a menu - whatever works best.
Note 1: Java has many ways to "get input from the user." The
JOptionPane.showInputDialog is the simplest way to get input,
other means of collecting input could have been used in this example such
as reading from labels and textareas.
This pattern works for 1 variable. If you want to input values for a number
of variables, it is best to reuse thiswhole pattern for each additional input.
Pattern A2: Handling Options
Purpose: To easily branch to the code corresponding to a choice
entered by a user
Pattern: Get Users Choice
Use a switch statement to branch to the code for the
user's choice
Example 1:
String input = JOptionPane.showInputDialog
("Choose: 1- First Choice, 2-Second Choice, or 3-Quit");
int choice = Integer.parseInt(input);
switch (choice) {
case 1:
ProcessChoice1();
break;
case 2:
ProcessChoice2();
break;
case 3:
System.exit(0)
break;
}
Discussion: One can also use an 'if - else' statement to handle user
choices. In most cases, however, the 'switch' statement produces
clearer code and is easier to write.
Note 1: Usually code like this is embedded in one of the looping
patterns below. See Pattern 'E2' below.
Note 2: The reason for the break statement is that it allows the next
statement to be executed.
More on 'switch' statement.
B. While Loops
These patterns are used to perform some activity
over and over. One of the key issues in repetitive activity is knowing when to
stop. Many of the patterns below will talk about ending or stopping
conditions. These are the conditions under which the loop will stop, for
example, if it has been executed 10 times or if the user has entered a -1. This
last is an example of a sentinel value - a value that signals the end of
a loop.
To decide when to stop, Java loops perform some test or set of tests each
time through the loop. These tests are collectively referred to as the test
condition.
Pattern B1: The Basic While Loop
Purpose: To loop through a set of instructions until some ending
or stopping condition is met.
Pattern: Assign a value to all variables involved in the test
condition
while the test condition is true
{
Do some set of instructions
Re-assign a value to at least one of the variables
in the test condition
}
Example 1: int counter = 10;
while (counter > 0)
{
/* some set of instructions */
counter--;
}
Example 2: int counter = 0;
while (counter < 10)
{
/* some set of instructions */
counter++;
}
Example 3: boolean found = false;
int counter = 10;
while ((counter > 0) && !found)
{
/* some set of instructions that include either
decrementing the counter or setting 'found' to true */
}
Discussion: The middle example is probably the simplest. In it,
the variable, 'counter' is set to 0 and each time through the
loop it is incremented by 1. When it has the value 9, the loop
has executed 10 times. (If you are uncomfortable with this statement,
count on your fingers starting with the value 0 and not the value 1.)
When the counter is incremented again to the value 10, the
loop stops because the test condition is now false.
The third example follows the same pattern except that now there
are two tests. The variables used in both tests are
initialized before the loop. Inside the loop either of these variables
can be changed and sooner or later the changes will cause one
or both of the tests to go false and the loop will terminate.
It is very important that all the variables involved in the test
condition be initialized before the loop begins execution. If
the reason for this is not clear, be sure you review the section
on loops and initialization in Chapter 3, Section IV
of "The Story of C++". The concept of loops and initilization
presented in "The Story of C++," can be applied to many
programming languages including java.
Note 1: If at least one of the variables involved in the test
condition is not re-assigned a value inside the WHILE loop,
the loop will never stop. This is called an infinite loop.
Note 2: The test condition variables can be assigned and re-assigned
using any of a number of valid Java statements. One common value
is to have the user enter a value using pattern A1
(See the next pattern for an example of this.) Another
common way (as done in the examples above) is to continuously add
or subtract a value to or from a variable.
Note 3: Be very careful in combining tests using the logical
operators. You may want to read the material on '&&'
and '||' in summary of operators.
This section on '&&' and '||' applies to the programming
language java as well.
Note 4: There is a 'for' loop pattern, Pattern 'C2', that also meets this
same purpose.
Pattern B2: The While Loop with Priming Read
Purpose: To loop through a set of instructions until the user
enters some sentinel value.
Pattern: Get value(s) from the user for the variable(s) in the
test condition
while the test condition is true
{
Do some set of instructions
Get value(s) from the user for the variable(s) in the test
condition
}
Example 1: String input = JOptionPane.showInputDialog
("PLEASE ENTER COST ");
int cost = Integer.parseInt(input);
while (cost != 0) /* cost is the initialized variable */
/*and 0 is the sentinel value*/
{
// some set of instructions to do something with the cost
input = JOptionPane.showInputDialog
("PLEASE ENTER COST ");
cost = Integer.parseInt(input);
}
Discussion: This pattern may well be the most important one in
the whole set in the sense that it is used the most and is not
obvious. The key point to this pattern is the priming read
or set of priming reads. A priming read is a read (input) instruction
that gives a value to a variable before that variable is used
in some kind of a test. In this case, the read takes place before
the while loop is entered.
This pattern is actually a variation of the previous one. The
only difference is that the sentinel value is entered by a user.
One could actually modify this code so that the input came from
any 'device' outside the program. For example, instead of the
input coming from a user typing values at a keyboard, the input
could come from a sensor device or even from a file. In either
case, there would still be some sentinel value indicating the
end of the data.
It is also possible to combine this pattern and the previous one.
In such a situation, some of the test condition variables have
their values changed by a user and some are changed by the code
itself.
Note 1: While it is common to use "JOptionPane.showInputDialog" to get
the input(s), one can use any other Java input instruction.
Pattern B3: Loop Until Valid Data Entered
Purpose: To loop through a set of instructions until the user
enters a 'valid' value. (This pattern
is most often used to force a user to enter one of a set of correct
or acceptable values.)
Pattern: Get a value from the user for the variable used in the
test condition
while the variable does not equal one of the 'valid' values
{
Display some error message indicating that the value entered is
not valid
Get a value from the user for the variable used in the test
condition
}
Example 1:
String input = JOptionPane.showInputDialog
("Please enter a number between 1 and 100.");
int number = Integer.parseInt(input);
while (number < 1 || number > 100)
{
input = JOptionPane.showInputDialog
("Your number is not between 1 and 100.\n"+
"Please enter a new value.\n");
number = Integer.parseInt(input);
}
Example 2:
String input = JOptionPane.showInputDialog
("DO YOU WANT TO CONTINUE? PLEASE ENTER (Y)ES OR (N)O");
String choice = input;
while (!choice.equals("Y") && !choice.equals("y") &&
!choice.equals("N") && !choice.equals("n"))
{
JOptionPane.showMessageDialog
(null, "YOUR ENTRY WAS INVALID");
/* person did not enter 'y' or 'n' */
input = JOptionPane.showInputDialog
("PLEASE ENTER (Y)ES OR (N)O");
choice = input;
}
Discussion: This is another variation of the basic loop pattern.
In almost all cases there is only one variable involved in the
test condition because one is looping until a 'valid' value
is entered and it would be difficult to keep track of valid values
for more than one variable at the same time. While there is only one
variable, there could be more than one test - allowing
the code to perform a complex set of tests for validity.
Pattern B4: Loop Until User Confirms Choice to
Quit
Purpose: To loop through a set of instructions until the user
signals and confirms that he or she is ready to quit.
Pattern: Set a Boolean variableindicating 'done' to FALSE
while the Boolean variable is false, also view data types
for information on data types.
{
Get user's choice
Process any choices other than quit using 'if' statements
or pattern A2
If choice = quit // if you used pattern A2, use a 'case' statement
{
Ask if user is sure
If answer = yes
{
Boolean variable = true
}
}
}
Example 1: boolean done;
char choice;
done = false;
while (!done)
switch (choice)
{
// process the various choices except the one
// for quitting
case 'Q':
case 'q':
done = true;
// the default choice
}
Discussion: Although the pattern includes the word 'if', it is more common for
this pattern to be implemented with a switch statement.
The code for the 'quit' case could include pattern B2.
As written here, if the user enters anything but 'Y' or 'y',
the loop continues.
C. The For Loop
The patterns in part 'B' can all be implemented as 'for' loops. Whether one
uses the while or for loop to implement an algorithm depends partially on
personal preference and partially on which instruction allows for cleaner code.
For example, pattern B1 above probably would be better as a 'for' loop and is
the first pattern below. On the other hand, pattern B3 is so much cleaner done
with a while loop that we won't even bother implementing a for loop version.
The for loop in other programming languages is often primarily used when one
knows beforehand how many times the loop will be executed. While this
instruction has been extended in power in Java, this is a good starting point.
When you know the number of times a loop will execute, either because it is
fixed in the program or because the number of times the loop will execute is
calculated or provided by input BEFORE the loop starts, use the 'for' statement.
Pattern C1: The Basic For Loop
Purpose: To loop through a set of instructions a set number of
times.
Pattern: for (variable1 = 0; variable1 < the number of times to loop; variable1++)
{
// Some set of instructions
}
Example 1: for (int i= 0; i < MAX_TIMES; i++)
{
// some set of instructions
}
Example 2: int numTimes;
String input = JOptionPane.showInputDialog
("Enter the number of times to loop\n.");
int numTimes = Integer.parseInt(input);
for (int count = 0; count < numTimes; count++)
{
// some set of instructions
}
Discussion: The first example uses a constant to determine the number of times
the loop executes. The second example has a user enter the number
of times. In either case, the number of times to loop is known
before the loop executes.
Compare this pattern with pattern B1. Example 1 here is
essentially the same as example 2 from pattern B1 except for the
constant.
Example 3 (below) shows a for loop similar to that of example
1 of pattern B1.
Example 3: for (int i= MAX_TIMES; i > 0; i--)
{
// some set of instructions
}
Pattern C2: The For Loop with Priming Read
Purpose: To loop through a set of instructions until the user
enters some sentinel value.
Pattern: Get value(s) from the user for the variable(s) in the
test condition
for (; a set of tests ; )
{
Do some set of instructions
Get value(s) from the user for the variable(s) in the test condition
}
Example 1: String input = JOptionPane.showInputDialog
("PLEASE ENTER COST (0 TO STOP)");
int cost = Integer.parseInt(input);
for (; cost > 0; ) /* cost is the initialized variable */
{
// some set of instructions to do something with the cost
input = JOptionPane.showInputDialog
("PLEASE ENTER COST (0 TO STOP)");
cost = Integer.parseInt(input);
}
Discussion: Since the initialization is done before the loop and the
variable is changed inside the loop, only the test
condition part is coded inside the for loop parentheses. You could
include the priming read and other inputs inside the code but
it would not be as readable. (See example 2 below.)
Example 2: int cost
for (String input = JOptionPane.showInputDialog
("PLEASE ENTER COST (0 TO STOP)"));
cost = Integer.parseInt(input);
if (cost > 0){
input = JOptionPane.showInputDialog
("PLEASE ENTER COST (0 TO STOP)");
cost = Integer.parseInt(input);
}
{
// some set of instructions
}
More on for
statement.
D. Counters, Running Totals and Averages
There are a number of patterns that include some looping pattern and add
some further capability. We will take a look at some of them here. Note that the
patterns themselves do not stipulate a specific looping pattern. Which one you
use depends on the context in which the pattern is used and on personal
preferences. The key point is that we are using basic patterns to build more
complex patterns. As with programming in general, the trick is to combine
patterns so as to correctly use all the elements of the individual patterns
while creating an integrated whole. Be sure you study carefully how the basic
patterns described above are combined in the patterns and examples below.
Pattern D1: The Counter Pattern Using a Loop
Purpose: To count the number of times a loop repeats; to implement
a counter.
Pattern: Initialize the Counter Variable to 0
Use some loop pattern - see Parts 'B' and 'C' above
Inside the loop pattern add the following code:
Counter Variable++
Example 1 int loopCount = 0;
String input = JOptionPane.showInputDialog
("PLEASE ENTER COST (0 TO STOP)");
int cost = Integer.parseInt(input);
// a loop to count the number of times a real cost is entered
while (cost != 0) /* cost is the initialized variable */
{
// some set of instructions to do something with
the cost
loopCount++;
input = JOptionPane.showInputDialog
("PLEASE ENTER COST (0 TO STOP)");
cost = Integer.parseInt(input);
}
Discussion: The key to this pattern is contained in the two lines:
int loopCount = 0;
and
loopCount++;
The rest of the code is purely to make the counter make some sense.
The first of these lines ensures that the code actually starts
counting from 0, while the second line does the actual counting.
Observe how this pattern sits half inside and half outside the
loop pattern. We do not want to repeatedly initialize the counter
to 0 so that part sits outside the loop. However, the line that
increments the counter needs to be inside the loop so that it
is repeatedly executed. Be careful to put the various elements
where they belong.
The variable 'loopCount' in the example starts at 0 and every
time through the loop it is incremented by one. When the loop
terminates, 'loopCount' will hold the number of times the loop
was executed.
In this example, nothing is done with the value in 'loopCount'.
In actual programs this value could be output or used as part
of some calculation as in the average pattern, D3, below.
Note 1: If you had some reason to begin your counter at some value
other than zero, that would be possible simply by initializing
the counter to the other value. Usually counter variables are
initialized to 0 because one wants to start counting from 0. However,
if, for example, you already knew that 556 of something existed
and now wanted to count the rest, you might begin the above code
fragment by initializing the counter to 556. If this was true
for example 1, the initialization line would then be:
int loopCount = 556;
Note 2: If you wanted to count by some value other than one, for
example, if you wanted to count by 5, you would change the
line:
count++ ; (or whatever counter variable you were using)
to:
count += 5; (or whatever value you wanted to count by).
Note 3: It is possible to implement counters where there are no
explicit loops although this is not as common and it has some
unique challenges. No code will be provided here but an example
of such a counter would be code that counted the number of times
a specific function was called. Outside the function a counter
would be initialized to 0 (or whatever value was appropriate),
while, inside, the function itself would be the increment instruction.
Note the similarity between this and the pattern under discussion.
In both cases, the initialization takes place outside the code
that repeats while the incrementing instruction must be inside
the code that repeats.
Pattern D2: The Sum Pattern Using a Loop
Purpose: To calculate the sum of some set of numbers.
Pattern: Initialize the Sum variable to 0
Use some loop pattern - see Sections 'B' and 'C' above
Inside the loop pattern add the following code::
Sum variable = Sum Variable + Amount To Add
Example 1 int sum = 0;
String input = JOptionPane.showInputDialog
("Please enter the first grade");
int grade= Integer.parseInt(input);
// a loop to add all the grades entered
while (grade != -1)
{
sum += grade;
input = JOptionPane.showInputDialog
("Please enter another grade");
grade = Integer.parseInt(input);
}
Discussion: The key to this pattern is contained in the two lines:
int sum = 0;
and
sum += grade;
The rest of the code is purely to make the summation make some
sense. The first of these lines ensures that the code actually
starts adding (summing) from 0 while the second line does the
actual adding. The pattern gives the long hand way of adding a
number to a summation (or running total) variable while
the code example demonstrates Java's shorthand way of doing the
same thing. If this code is not clear, see
in summation in Java.
Observe how this pattern sits half inside and half outside
the loop pattern. We do not want to repeatedly initialize the
summation variable to 0, so that part sits outside the loop. However,
the line that does the adding needs to be inside the loop so that
it is repeatedly executed. Be careful to put the various elements
where they belong.
Note 1: If you had some reason to begin your running total at some
value other than zero, that would be possible simply by initializing
the running total variable to the other value. Usually running
total variables are initialized to 0. However, if, for example,
you had already found that the sum of a set of grades was 556,
you might begin the above code fragment by initializing sum to
556 as is:.
int sum = 556;
Note 2: The sentinel value here was chosen under the assumption
that a student would never receive a grade of -1. Other sentinel
values are possible.
D3: The Average Pattern
Purpose: To calculate the average of some set of numbers.
Pattern: Use the counter and sum patterns with some loop pattern
After the loop pattern:
if Counter Variable != 0 then
{
average = Sum Variable / Counter Variable
Display average
}
else
{
Display some message indicating there was nothing to take the
average of.
}
Example 1: int sumGrades = 0;
int numGrades = 0;
int totalGrade =0;
int grade;
int averageGrade;
String input = JOptionPane.showInputDialog
("Please enter the first grade");
grade = Integer.parseInt(input);
while (grade != -1)
{
sumGrades= sumGrades+grade;
numGrades++;
input = JOptionPane.showInputDialog
("Please enter another grade or -1 to get average grade");
grade = Integer.parseInt(input);
}
if (numGrades != 0)
{
totalGrade = sumGrades / numGrades;
averageGrade = totalGrade;
JOptionPane.showMessageDialog
(null, "The average grade is: " + averageGrade);
}
else
{
JOptionPane.showMessageDialog
(null, "There were no grades to output\n");
}
Discussion: This patterns combines three patterns to make a fourth.
Notice that although both the counter and sum patterns call for
a loop, we only use one loop in this pattern. Both the sum and
counter patterns use the same loop.
Note 1: Although in this pattern any average that is calculated
is also output, this is not the only way to handle this. One could
instead return the average if this code was part of some function
or one could use the average in some further calculation.
Note 2: There are also a number of ways of handling the situation
where no grades are input. In many cases, one does not want to
display an error message. If this were a function that returned
the average, one might, for example, wish to also return a code
indicating whether the average was successfully calculated.
E. Miscellaneous Patterns
Pattern E1: Finding the Largest or Smallest
Purpose: To find the largest or smallest number in a list entered
by a user.
Pattern For Finding the Largest:
Get the first value from the user and put it into variable1.
aValueEntered = true
if variable1 != sentinel value
{
largest value so far = variable1;
Get another value from the user and put into variable1
}
else
{
aValueEntered = false
}
while (variable1 != sentinel value)
{
if (variable1 > largest value so far)
{
largest value so far = variable1;
}
Get the next value from the user and put into variable1
}
if (aValueEntered)
{
Display largest value so far
}
else
{
Display "No values were entered".
}
Example 1: int number;
int largestValueSoFar=0;
boolean aValueEntered = true;
String value = "";
String input = JOptionPane.showInputDialog
("Enter a number or -1 to stop\n");
number = Integer.parseInt(input);
if (number != -1)
{
largestValueSoFar = number;
input = JOptionPane.showInputDialog
("Enter a number or -1 to stop\n");
number = Integer.parseInt(input);
}
else
{
aValueEntered = false;
}
while (number != -1)
{
if (number > largestValueSoFar)
{
largestValueSoFar = number;
}
input = JOptionPane.showInputDialog
("Enter a number or -1 to stop\n");
number = Integer.parseInt(input);
}
if (aValueEntered)
{
value += "The largest value entered was: "+ largestValueSoFar;
JOptionPane.showMessageDialog(null, value);
}
else
{
JOptionPane.showMessageDialog(null,"No values were entered\n");
}
Discussion: This algorithm works by always keeping track of the
largest value encountered so far. The first value entered is the
largest value encountered until a larger value is entered. Thus,
it is immediately stored in the variable largest value so far.
As each additional value is entered, it is compared with the value in
this variable, and it replaces the value in the variable if
it is truly larger.
Since the sentinel value (-1 in this example) should not be considered
one of the values entered, special care must be taken with it.
The Boolean variable 'aValueEntered' is used here to make sure
that at least one value other than -1 was entered.
The pattern for finding the smallest value entered is the same
except that the comparison symbol '>' is changed to '<'.
(One might also wish to change the name of the variable
largest value so far to smallest so far to make the code
readable but technically, this is not necessary.
Note 1: This pattern simply outputs the value found. One could
do many other things with the largest or smallest value, depending
on the requirements of one's program.
Note 2: It is common for problems to say something like "Give
me the name of the person with the smallest or largest ....".
Example 2 (below) adds this feature.
Example 2: int grade=0;
int largestGradeSoFar=0;
String largestName = "";
String name ="";
String nameWithLargestGrade= "";
String input = JOptionPane.showInputDialog
("Please enter the name of a person:\n"
+"Enter'*' to signify no more names");
name = input;
if (!name.equals("*"))
{
input = JOptionPane.showInputDialog
("Please enter the final grade for this person");
grade = Integer.parseInt(input);
largestGradeSoFar = grade;
// This grade is the largest seen so far so...
nameWithLargestGrade = name;
// Store the name of the person with largest grade seen so far
input = JOptionPane.showInputDialog
("Please enter the name of a person:\n"
+"Enter'*' to signify no more names");
name = input;
}
else
{
nameWithLargestGrade = " ";
// There were no valid names entered so store a blank name
}
while (!name.equals("*"))
{
input = JOptionPane.showInputDialog
("Please enter the final grade for the next person");
grade = Integer.parseInt(input);
if (grade > largestGradeSoFar)
{
largestGradeSoFar = grade;
nameWithLargestGrade = name;
}
input = JOptionPane.showInputDialog
("Please enter the name of the next person:\n"
+"Enter'*' to signify no more names");
name = input;
}
largestName += "The person with the largest grade: "+ nameWithLargestGrade;
JOptionPane.showMessageDialog
(null, largestName);
Note 3: If no valid name is entered, the variable 'name' holds
a blank string and that is what will be output.
Pattern E2. Handling Options
Purpose: To continuously cause a program to branch to the appropriate
code for each option in a set of user entered options.
Pattern:
while
{ Get user choice
switch (user choice)
{
A series of case statements - at least one for each option
}
}
Example 1: String input = JOptionPane.showInputDialog
("Choose: 1- First Choice, 2-Second Choice, or 3-Quit");
int choice = Integer.parseInt(input);
while (choice !=3){
switch (choice) {
case 1:
ProcessChoice1();
break;
case 2:
ProcessChoice2();
break;
case 3:
System.exit(0);
break;
}// end switch
// default case statement if needed
} // end while
Discussion: This pattern is actually an extension of Pattern A2.
The use of the switch statement for handling choices
is discussed in great detail in the online Java Tutorial at
Java.sun.com,switch statement.
Pattern E3. A General Prompt Producer
Purpose: To allow one function to produce different outputs -
in the form of messages or prompts or whatever.
Pattern: Declare a function with a string parameter to receive
the message to be output. In the function use a cout
to output the string parameter
Example 1: Void OutputPrompt(output)
{
String output=JOptionPane.showMessageDialog
(null,output);
}
Example 2: A function that returns a string value entered in response
to a prompt.
public String GetString()
{
String reply = JOptionPane.showInputDialog
("Enter 'Y' to continue or 'N' to quit:");
return reply;
}
Discussion: The idea here is to simply pass in whatever string
one wants to output. This approach can be used for any kind of
output. The first example is the most general and demonstrates
how any kind of output can be performed. The second example demonstrates
the use of this approach with using the JOptionPane.showInputDialog to
to return input from the user.
Such an approach is most beneficial when one has many very similar
outputs or prompts to generate.
F. Array Manipulation Patterns
Much of the code for handling arrays involves "walking through" the array one element at a time.
This usually requires some kind of a loop. Usually we use a 'for' statement when we know how
many times the loop will execute - as when the goal is to perform some action on all the
elements of an array. For other purposes, we can use the 'for' or 'while' statements, or even
the 'do…while' statement.
Pattern F1: Performing an Action on Each Element of an
Array
Purpose: To work with or perform some action on all the elements
of an array
Pattern: Declare or somehow have access to some kind of an array.
Here, we assume that the variable An Array represents
an array of some type.
for (int index = 0; index < MAX_ELEMENTS;index++)
{
Perform some operation on An Array[ index ]
}
Example 1:
/* A constant call MAX_GRADES has been declared*/
/* and given some value. An array called */
/* grades has been declared of size MAX_GRADE */
/* and filled with student grades. */
/* */
/* Assume that each grade is an integer */
/* representing the score of some test. */
/* */
/* See F1, Example 4 for example code of */
/* how to put user input into an array. */
for (int testNum = 0; testNum < MAX_GRADES; testNum++)
{
testCounter=testNum + 1;
JOptionPane.showMessageDialog
(null, "The grade for test "+ testCounter+ " is: "+ grades[testNum]);
}
Discussion: Any action can be performed inside the loop. One can
input values into the elements of an array, sum up the elements,
do some comparison, modify the elements, use each element in a
calculation etc.
Note 1: MAX_GRADES in the example here probably represents the
number of elements in the array. If you wished to use only part
of the array, you could change the starting point by initializing
the index variable ('testNum' in the example) to some positive
value other than 0 and/or compare it with some value other than
the value representing the number of elements in the array. In
the example 2 below, we just want to output the first 10 elements
of the array. In example 3, we wish to output the scores
for tests 10 through 20.
Example 2: for (int testNum = 0; testNum < 10; testNum++)
{
testCounter=testNum + 1;
JOptionPane.showMessageDialog
(null, "The grade for test "+ testCounter+ " is: "+ grades[testNum]);
}
Example 3: for (int testNum = 9; testNum < 20; testNum++)
{
testCounter=testNum + 1;
JOptionPane.showMessageDialog
(null, "The grade for test "+ testCounter+ " is: "+ grades[testNum]);
}
Note 3: 'testNum' starts at 9 because the array counts from 0.
For more on this subject go to 'for'
loops with arrays.
Example 4: for (int i=0; i < MAX_GRADES; i++)
{
String input = JOptionPane.showInputDialog
("Enter a grade: ");
grade = Integer.parseInt(input);
grades[i] = grade;
}
Note 4: Example 4 shows how by using the JOptionPane.showInputDialog,
the test scores can be inputed by the user and stored in the variable
called 'grade.' Each grade is added to the array 'grades' by the code
'grade[i] = grade'.
Pattern F2: Searching an Array
Purpose: To search for some value in an array
Pattern: Declare or somehow have access to some kind of an array,
Here, we assume that the variable An Array represents
an array of some type.
Set found to false
Set index to 0
Get the value to search for
while not found and index < MAX_ELEMENTS
{
if value = AnArray [ index ]
{
found = true
}
else
{
index++
}
}
if found
{
// do what is to be done if value is found
}
else
{
// do what is to be done if value not found
}
Example 1: /*Search for some test score in the array declared*/
/*in pattern F1 */
boolean found = false;
int testNum = 0;
scoreToFind = GetScoreToFind();
while (!found && testNum < MAX_GRADES)
{
if (scoreToFind == grades[testNum])
{
found = true;
}
else
{
testNum++;
}
}
if (found)
{
int testCount =0;
testCount=testNum+1;
JOptionPane.showMessageDialog
(null, "A test score of " + (scoreToFind) +
" was achieved first on test " + (testCount));
// the variable testCount is to handle counting from 0
}else
{
JOptionPane.showMessageDialog
(null, "No test with this score was found");
}
Discussion: The comparison to find out if a match exists can be more complex,
involving class properties and other or more complex test
conditions. For example, one might be looking for the first grade,
greater than some value or for a match with someone's address, where
the address is represented as many properties of a class.
Also, many different things can be done after a search has been
completed. It is common, for example, for a search to be coded
as a method and for the result to be returned. The result (what
is returned) can be a piece of data, the index of the element
found, and/or the success or failure of the search.
Pattern G1: Opening Files for Input
Purpose: To open a file for input
Pattern: Get the name of the File (or have it hard coded)
(Here we will say it is stored in the variable filename.)
String userinput=JOptionPane.showInputDialog("Enter the filename:");
String filename=userinput;
BufferedReader f = new BufferedReader
(new FileReader(filename));
Example 1: /*This simple program reads a text file created in a text editor
*(e.g. notepad or textpad).
*/
import java.io.*;
import javax.swing.*;
public class ReadFile{
public static void main(String [] args){
String userinput=JOptionPane.showInputDialog("Enter the filename:");
String filename=userinput;
String myline;
try{
BufferedReader f = new BufferedReader
(new FileReader(filename));
while((myline = f.readLine()) !=null)
System.out.println(myline);
f.close();
} catch(IOException error){
error.printStackTrace();
}
}
}
Discussion: Java makes use of a 'buffer' to store blocks of data called a
BufferedReader. The purpose of this 'buffer' is to increase
efficiency in accessing external data. The readLine method
is used to read and return a line of text as a string
from this buffer. When the readLine method returns a value of
null (usually indicating the end of a file) the while loop ends.
After the file was read, it is closed. If you wish to know more,
then learn about filestreams.
Note: When opening and closing files Java requires that a type of
error called an “Exception” be handled. The “try” and “catch” code
you see in this example does this. You can simply follow what is
shown here or learn more about exceptions.