175 20231127090431 Ch05a
175 20231127090431 Ch05a
Chapter 5
Program Logic and Indefinite Loops
A deceptive problem...
• Write a method printNumbers that prints each number from
1 to a given maximum, separated by commas.
should print:
1, 2, 3, 4, 5
2
Flawed solutions
• public static void printNumbers(int max) {
for (int i = 1; i <= max; i++) {
System.out.print(i + ", ");
}
System.out.println(); // to end the line of output
}
3
Fence post analogy
• We print n numbers but need only n - 1 commas.
• Similar to building a fence with wires separated by posts:
– If we use a flawed algorithm that repeatedly places a post + wire,
the last post will have an extra dangling wire.
4
Fencepost loop
• Add a statement outside the loop to place the initial "post."
– Also called a fencepost loop or a "loop-and-a-half" solution.
place a post.
for (length of fence - 1) {
place some wire.
place a post.
}
5
Fencepost method solution
public static void printNumbers(int max) {
System.out.print(1);
for (int i = 2; i <= max; i++) {
System.out.print(", " + i);
}
System.out.println(); // to end the line
}
7
Fencepost answer
// Prints all prime numbers up to the given max.
public static void printPrimes(int max) {
if (max >= 2) {
System.out.print("2");
for (int i = 3; i <= max; i++) {
if (countFactors(i) == 2) {
System.out.print(", " + i);
}
}
System.out.println();
}
}
// Returns how many factors the given number has.
public static int countFactors(int number) {
int count = 0;
for (int i = 1; i <= number; i++) {
if (number % i == 0) {
count++; // i is a factor of number
}
}
return count;
}
8
while loops
9
Categories of loops
• definite loop: Executes a known number of times.
– The for loops we have seen are definite loops.
• Print "hello" 10 times.
• Find all the prime numbers up to an integer n.
• Print each odd number between 5 and 127.
10
The while loop
• while loop: Repeatedly executes its
body as long as a logical test is true.
while (test) {
statement(s);
}
• Example:
int num = 1; // initialization
while (num <= 200) { // test
System.out.print(num + " ");
num = num * 2; // update
}
// output: 1 2 4 8 16 32 64 128
11
Example while loop
// finds the first factor of 91, other than 1
int n = 91;
int factor = 2;
while (n % factor != 0) {
factor++;
}
System.out.println("First factor is " + factor);
// output: First factor is 7
12
Sentinel values
• sentinel: A value that signals the end of user input.
– sentinel loop: Repeats until a sentinel value is seen.
13
Flawed sentinel solution
• What's wrong with this solution?
Scanner console = new Scanner(System.in);
int sum = 0;
int number = 1; // "dummy value", anything but 0
while (number != 0) {
System.out.print("Enter a number (0 to quit): ");
number = console.nextInt();
sum = sum + number;
}
14
Changing the sentinel value
• Modify your program to use a sentinel value of -1.
– Example log of execution:
Enter a number (-1 to quit): 15
Enter a number (-1 to quit): 25
Enter a number (-1 to quit): 10
Enter a number (-1 to quit): 30
Enter a number (-1 to quit): -1
The total is 80
15
Changing the sentinel value
• To see the problem, change the sentinel's value to -1:
Scanner console = new Scanner(System.in);
int sum = 0;
int number = 1; // "dummy value", anything but -1
16
The problem with our code
• Our code uses a pattern like this:
sum = 0.
while (input is not the sentinel) {
prompt for input; read input.
add input to the sum.
}
18
Correct sentinel code
Scanner console = new Scanner(System.in);
int sum = 0;
19
Sentinel as a constant
public static final int SENTINEL = -1;
...
Scanner console = new Scanner(System.in);
int sum = 0;
– Example:
Random rand = new Random();
int randomNumber = rand.nextInt(10); // 0-9
22
Generating random numbers
• Common usage: to get a random number from 1 to N
int n = rand.nextInt(20) + 1; // 1-20 inclusive
int n = rand.nextInt(7) + 4;
23
Random questions
• Given the following declaration, how would you get:
Random rand = new Random();
26
Random answer
// Rolls two dice until a sum of 7 is reached.
import java.util.*;
public class Dice {
public static void main(String[] args) {
Random rand = new Random();
int tries = 0;
int sum = 0;
while (sum != 7) {
// roll the dice once
int roll1 = rand.nextInt(6) + 1;
int roll2 = rand.nextInt(6) + 1;
sum = roll1 + roll2;
System.out.println(roll1 + " + " + roll2 + " = " + sum);
tries++;
}
System.out.println("You won after " + tries + " tries!");
}
}
27
Random question
• Write a program that plays an adding game.
– Ask user to solve random adding problems with 2-5 numbers.
– The user gets 1 point for a correct answer, 0 for incorrect.
– The program stops after 3 incorrect answers.
4 + 10 + 3 + 10 = 27
9 + 2 = 11
8 + 6 + 7 + 9 = 25
Wrong! The answer was 30
5 + 9 = 13
Wrong! The answer was 14
4 + 9 + 9 = 22
3 + 1 + 7 + 2 = 13
4 + 2 + 10 + 9 + 7 = 42
Wrong! The answer was 32
You earned 4 total points.
28
do/while question
• Modify the previous Dice program to use do/while.
2 + 4 = 6
3 + 5 = 8
5 + 6 = 11
1 + 1 = 2
4 + 3 = 7
You won after 5 tries!
29
Random answer
// Asks the user to do adding problems and scores them.
import java.util.*;
30
Random answer 2
...
// Builds one addition problem and presents it to the user.
// Returns 1 point if you get it right, 0 if wrong.
public static int play(Scanner console, Random rand) {
// print the operands being added, and sum them
int operands = rand.nextInt(4) + 2;
int sum = rand.nextInt(10) + 1;
System.out.print(sum);
for (int i = 2; i <= operands; i++) {
int n = rand.nextInt(10) + 1;
sum += n;
System.out.print(" + " + n);
}
System.out.print(" = ");
// read user's guess and report whether it was correct
int guess = console.nextInt();
if (guess == sum) {
return 1;
} else {
System.out.println("Wrong! The answer was " + total);
return 0;
}
}
}
31
The do/while loop
• do/while loop: Performs its test at the end of each repetition.
– Guarantees that the loop's {} body will run at least once.
do {
statement(s);
} while (test);
33