Chapter 5: Conditionals and Loops
Lab Exercises
Topics Lab Exercises
The while statement PreLab Exercises
Counting and Looping (submit)
A Guessing Game (submit)
The for statement Finding Maximum and Minimum Values (extra credit)
Using the Coin Class (submit)
Prelab Exercises
Section 5.5
In a while loop, execution of a set of statements (the body of the loop) continues until the boolean expression controlling the loop (the condition) becomes false. As for an if statement, the condition must be enclosed in parentheses. For example, the loop below prints the numbers from 1 to to LIMIT:
final int LIMIT = 100; // setup
int count = 1;
while (count <= LIMIT) // condition
{ // body
System.out.println(count); // -- perform task
count = count + 1; // -- update condition
}
There are three parts to a loop:
· The setup, or initialization. This comes before the actual loop, and is where variables are initialized in preparation for the first time through the loop.
· The condition, which is the boolean expression that controls the loop. This expression is evaluated each time through the loop. If it evaluates to true, the body of the loop is executed, and then the condition is evaluated again; if it evaluates to false, the loop terminates.
· The body of the loop. The body typically needs to do two things:
· Do some work toward the task that the loop is trying to accomplish. This might involve printing, calculation, input and output, method calls—this code can be arbitrarily complex.
· Update the condition. Something has to happen inside the loop so that the condition will eventually be false—otherwise the loop will go on forever (an infinite loop). This code can also be complex, but often it simply involves incrementing a counter or reading in a new value.
Sometimes doing the work and updating the condition are related. For example, in the loop above, the print statement is doing work, while the statement that increments count is both doing work (since the loop's task is to print the values of count) and updating the condition (since the loop stops when count hits a certain value).
The loop above is an example of a count-controlled loop, that is, a loop that contains a counter (a variable that increases or decreases by a fixed value—usually 1—each time through the loop) and that stops when the counter reaches a certain value. Not all loops with counters are count-controlled; consider the example below, which determines how many even numbers must be added together, starting at 2, to reach or exceed a given limit.
final int LIMIT = 16; TRACE
int count = 1; sum nextVal count
int sum = 0; --- ------- -----
int nextVal = 2;
while (sum < LIMIT)
{
sum = sum + nextVal;
nextVal = nextVal + 2;
count = count + 1;
}
System.out.println("Had to add together " + (count-1) + " even numbers " +
"to reach value " + LIMIT + ". Sum is " + sum);
Note that although this loop counts how many times the body is executed, the condition does not depend on the value of count.
Not all loops have counters. For example, if the task in the loop above were simply to add together even numbers until the sum reached a certain limit and then print the sum (as opposed to printing the number of things added together), there would be no need for the counter. Similarly, the loop below sums integers input by the user and prints the sum; it contains no counter.
int sum = 0; //setup
String keepGoing = "y";
int nextVal;
while (keepGoing.equals("y") || keepGoing.equals("Y"))
{
System.out.print("Enter the next integer: "); //do work
nextVal = scan.nextInt();
sum = sum + nextVal;
System.out.println("Type y or Y to keep going"); //update condition
keepGoing = scan.next();
}
System.out.println("The sum of your integers is " + sum);
Exercises
1. In the first loop above, the println statement comes before the value of count is incremented. What would happen if you reversed the order of these statements so that count was incremented before its value was printed? Would the loop still print the same values? Explain.
2. Consider the second loop above.
a. Trace this loop, that is, in the table next to the code show values for variables nextVal, sum and count at each iteration. Then show what the code prints.
b. Note that when the loop terminates, the number of even numbers added together before reaching the limit is count-1, not count. How could you modify the code so that when the loop terminates, the number of things added together is simply count?
3. Write a while loop that will print "I love computer science!!" 100 times. Is this loop count-controlled?
4. Add a counter to the third example loop above (the one that reads and sums integers input by the user). After the loop, print the number of integers read as well as the sum. Just note your changes on the example code. Is your loop now count-controlled?
5. The code below is supposed to print the integers from 10 to 1 backwards. What is wrong with it? (Hint: there are two problems!) Correct the code so it does the right thing.
count = 10;
while (count >= 0)
{
System.out.println(count);
count = count + 1;
}
Counting and Looping
The program in LoveCS.java prints "I love Computer Science!!" 10 times. Copy it to your directory and compile and run it to see how it works. Then modify it as follows:
// ****************************************************************
// LoveCS.java
//
// Use a while loop to print many messages declaring your
// passion for computer science
// ****************************************************************
public class LoveCS
{
public static void main(String[] args)
{
final int LIMIT = 10;
int count = 1;
while (count <= LIMIT){
System.out.println("I love Computer Science!!");
count++;
}
}
}
1. Instead of using constant LIMIT, ask the user how many times the message should be printed. You will need to declare a variable to store the user's response and use that variable to control the loop. (Remember that all caps is used only for constants!)
2. Number each line in the output, and add a message at the end of the loop that says how many times the message was printed. So if the user enters 3, your program should print this:
1 I love Computer Science!!
2 I love Computer Science!!
3 I love Computer Science!!
Printed this message 3 times.
3. If the message is printed N times, compute and print the sum of the numbers from 1 to N. So for the example above, the last line would now read:
Printed this message 3 times. The sum of the numbers from 1 to 3 is 6.
Note that you will need to add a variable to hold the sum.
A Guessing Game
File Guess.java contains a skeleton for a program to play a guessing game with the user. The program should randomly generate an integer between 1 and 10, then ask the user to try to guess the number. If the user guesses incorrectly, the program should ask them to try again until the guess is correct; when the guess is correct, the program should print a congratulatory message.
1. Using the comments as a guide, complete the program so that it plays the game as described above.
2. Modify the program so that if the guess is wrong, the program says whether it is too high or too low. You will need an if statement (inside your loop) to do this.
3. Now add code to count how many guesses it takes the user to get the number, and print this number at the end with the congratulatory message.
4. Finally, count how many of the guesses are too high and how many are too low. Print these values, along with the total number of guesses, when the user finally guesses correctly.
// ****************************************************************
// Guess.java
//
// Play a game where the user guesses a number from 1 to 10
//
// ****************************************************************
import java.util.Scanner;
import java.util.Random;
public class Guess
{
public static void main(String[] args)
{
int numToGuess; //Number the user tries to guess
int guess; //The user's guess
Scanner scan = new Scanner(System.in);
Random generator = new Random();
//randomly generate the number to guess
//print message asking user to enter a guess
//read in guess
while ( ) //keep going as long as the guess is wrong
{
//print message saying guess is wrong
//get another guess from the user
}
//print message saying guess is right
}
}
Finding Maximum and Minimum Values
A common task that must be done in a loop is to find the maximum and minimum of a sequence of values. The file Temps.java contains a program that reads in a sequence of hourly temperature readings over a 24-hour period. You will be adding code to this program to find the maximum and minimum temperatures. Do the following:
1. Save the file to your directory, open it and see what's there. Note that a for loop is used since we need a count-controlled loop. Your first task is to add code to find the maximum temperature read in. In general to find the maximum of a sequence of values processed in a loop you need to do two things:
· You need a variable that will keep track of the maximum of the values processed so far. This variable must be initialized before the loop. There are two standard techniques for initialization: one is to initialize the variable to some value smaller than any possible value being processed; another is to initialize the variable to the first value processed. In either case, after the first value is processed the maximum variable should contain the first value. For the temperature program declare a variable maxTemp to hold the maximum temperature. Initialize it to -1000 (a value less than any legitimate temperature).
· The maximum variable must be updated each time through the loop. This is done by comparing the maximum to the current value being processed. If the current value is larger, then the current value is the new maximum. So, in the temperature program, add an if statement inside the loop to compare the current temperature read in to maxTemp. If the current temperature is larger set maxTemp to that temperature. NOTE: If the current temperature is NOT larger, DO NOTHING!
2. Add code to print out the maximum after the loop. Test your program to make sure it is correct. Be sure to test it on at least three scenarios: the first number read in is the maximum, the last number read in is the maximum, and the maximum occurs somewhere in the middle of the list. For testing purposes you may want to change the HOURS_PER_DAY variable to something smaller than 24 so you don't have to type in so many numbers!
3. Often we want to keep track of more than just the maximum. For example, if we are finding the maximum of a sequence of test grades we might want to know the name of the student with the maximum grade. Suppose for the temperatures we want to keep track of the time (hour) the maximum temperature occurred. To do this we need to save the current value of the hour variable when we update the maxTemp variable. This of course requires a new variable to store the time (hour) that the maximum occurs. Declare timeOfMax (type int) to keep track of the time (hour) the maximum temperature occurred. Modify your if statment so that in addition to updating maxTemp you also save the value of hour in the timeOfMax variable. (WARNING: you are now doing TWO things when the if condition is TRUE.)
4. Add code to print out the time the maximum temperature occurred along with the maximum.
5. Finally, add code to find the minimum temperature and the time that temperature occurs. The idea is the same as for the maximum. NOTE: Use a separate if when updating the minimum temperature variable (that is, don't add an else clause to the if that is already there).
// **********************************************************
// Temps.java
//
// This program reads in a sequence of hourly temperature
// readings (beginning with midnight) and prints the maximum
// temperature (along with the hour, on a 24-hour clock, it
// occurred) and the minimum temperature (along with the hour
// it occurred).
// **********************************************************
import java.util.Scanner;
public class Temps
{
//----------------------------------------------------
// Reads in a sequence of temperatures and finds the
// maximum and minimum read in.
//----------------------------------------------------
public static void main (String[] args)
{
final int HOURS_PER_DAY = 24;
int temp; // a temperature reading
Scanner scan = new Scanner(System.in);
// print program heading
System.out.println ();
System.out.println ("Temperature Readings for 24 Hour Period");
System.out.println ();
for (int hour = 0; hour < HOURS_PER_DAY; hour++)
{
System.out.print ("Enter the temperature reading at " + hour +
" hours: ");
temp = scan.nextInt();
}
// Print the results
}
}
Using the Coin Class
The Coin class from Listing 5.4 in the text is in the file Coin.java. Copy it to your directory, then write a program to find the length of the longest run of heads in 100 flips of the coin. A skeleton of the program is in the file Runs.java. To use the Coin class you need to do the following in the program:
1. Create a coin object.
2. Inside the loop, you should use the flip method to flip the coin, the toString method (used implicitly) to print the results of the flip, and the getFace method to see if the result was HEADS. Keeping track of the current run length (the number of times in a row that the coin was HEADS) and the maximum run length is an exercise in loop techniques!
3. Print the result after the loop.
// *******************************************************************
// Coin.java Author: Lewis and Loftus
//
// Represents a coin with two sides that can be flipped.
// *******************************************************************
public class Coin
{
public final int HEADS = 0;
public final int TAILS = 1;
private int face;
// ---------------------------------------------
// Sets up the coin by flipping it initially.
// ---------------------------------------------
public Coin ()
{
flip();
}
// -----------------------------------------------
// Flips the coin by randomly choosing a face.
// -----------------------------------------------
public void flip()
{
face = (int) (Math.random() * 2);
}
// ---------------------------------------------------------
// Returns true if the current face of the coin is heads.
// ---------------------------------------------------------
public boolean isHeads()
{
return (face == HEADS);
}
// ----------------------------------------------------
// Returns the current face of the coin as a string.
// ----------------------------------------------------
public String toString()
{
String faceName;
if (face == HEADS)
faceName = "Heads";
else
faceName = "Tails";
return faceName;
}
}
// ********************************************************************
// Runs.java
//
// Finds the length of the longest run of heads in 100 flips of a coin.
// ********************************************************************
public class Runs
{
public static void main (String[] args)
{
final int FLIPS = 100; // number of coin flips
int currentRun = 0; // length of the current run of HEADS
int maxRun = 0; // length of the maximum run so far
// Create a coin object
// Flip the coin FLIPS times
for (int i = 0; i < FLIPS; i++)
{
// Flip the coin & print the result
// Update the run information
}
// Print the results
}
}