REPETITION  CONTROL  STRUCTURES -  LOOPS (while)

TOPICS


·       The while statement: definition, syntax

·       Loop terminology

·       Loops using the while statement:

o   Counter-controlled loops (definite loops)

o   Event-controlled loops  (indefinite loops)

§  Sentinel-controlled loops

§  EOF-controlled loops

§  Flag-controlled loops

·       Looping subtasks (counting, summing, etc)

·       Choosing the correct type of  loop for a given problem.

·       Nested while loops.

·       Sample Programs (Program#1, Program #2) and Exercises

OUTLINE



1. The while statement

while(Expression)//test
{
     <statement>
     <statement>
     .  // loop body
     .  // loop body
}

      Note1:  The loop body can be a single statement, a null statement, or a block.
      Note2:  Do not put a semicolon after
while(Expression) - null statement
      Note3:  Do not interchange
if and while thinking that both statements have conditional tests. What is the difference?

Description: Description: Description: C:\Courses-NOW\Webpage\236\LectureNotes\L6-Loop.JPG

 
int x = 0;
while ( x <= 10) {
   x = x + 1;
   System.out.println("x =  " + x);
}

2.  Loop Terminology

3. Loops Using the while Statement


Example of types of loops:

Counter-controlled loop

Read exactly 100 numbers

Sentinel-controlled loop 

Read some numbers, until a special value, chosen by you, which is not a legal  value, is found

End-of-file controlled loop

Read all the numbers in the file, no matter how many they are

Flag-controlled loop

Read some numbers, until a special value is found. When found, change the value of the flag.

Another example: The "temperature" problem (to be discussed with all types of loops)

Counter-controlled loop

Read exactly 100 temperatures

Sentinel-controlled loop 

Read temperatures, until a special value, chosen by you, which is not a legal  value, is found (Ex: temp = 999)

End-of-file controlled loop

Read all temperatures in the file, no matter how many they are

Flag-controlled loop

Read temperatures, until a dangerously high value (Ex: temp >= 200) is found. When found, change the value of the flag (from true/false to false/true).


 


                    1. Initialize:  the loop-control variable should be somehow initialized before the loop
                    2. Test (for continuing the loop)
                    3.
Update:  the loop-control variable should be somehow updated inside the loop (to avoid infinite loops)

1. Initialize the counter before the loop
2. Test (for continuing the loop)
3.
Update:  the counter should be updated inside the loop


 

int N = some value either inputted by the user, or some specified value;
int counter = 0; //initialize
while (counter < N) //test
{
    statements
    ...
    counter++; //update
}

 
int counter = 0; // initialize counter
while(counter <= 4) // test
{
   System.out.print("\t" + counter); // repeated action
   counter++ ;  // update counter
}
System.out.println("\nDone");


           int number = 1;

 while (number <= 200) {
     System.out.print(number + " ");
     number *= 2;
 }
 SAMPLE OUTPUT:
 1 2 4 8 16 32 64 128

 
// Counter-controlled loop
import java.util.Scanner;

class Temp_Counter {
    public static final int MAX = 10;

    public static void main(String[] args){
       //Declarations
        Scanner input = new Scanner(System.in);
        double temp;
        double sum = 0;
        double avg;
        int loopCount = 1; //initialize counter
        while (loopCount <= MAX) //test counter: exactly MAX iterations
        {
            System.out.print("Enter a temperature: ");
            temp = input.nextDouble();
            sum = sum + temp;
            loopCount = loopCount + 1;//update counter
        }
        avg = sum / MAX;
        System.out.println("\nThe average temperature is: " + avg);
    }
}

SAMPLE OUTPUT:
Enter a temperature: 39
Enter a temperature: 56
Enter a temperature: 34
Enter a temperature: 56
Enter a temperature: 78
Enter a temperature: 67
Enter a temperature: 56
Enter a temperature: 78
Enter a temperature: 89
Enter a temperature: 59
The average temperature is: 61.2
 

....
char answer;
Scanner input = new Scanner(System.in);

while (answer == 'Y') {
    System.out.println("Hello, hello!");
    System.out.print("Continue?(y/n): ");
    answer = input.next().charAt(0);
}
 

Example 5: This loop will be executed forever. Why?

....
char answer;
answer = 'y';
while (answer == 'y') {
    System.out.println("Hello, hello!");
}

Note: Pay attention when testing for equality!

 
while(ans = 'y') // wrong! Don't use =, but ==
while(ans == 'y'); // wrong! Don't use ; after while
while((ans =='Y') && (ans =='y')) // wrong! Can't be both
while((ans =='Y') || (ans =='y')) // CORRECT

1. Initialize: The first set of data values have to be read ==> read just before entering the loop - priming read
2. Test the sentinel
3. Update: The next set of data value has to be read ==> the last statement inside the loop body - next read.


     Priming read: input first data item into variable; //initialize sentinel

while (variable != sentinel) //test sentinel
{
    statements
    ...
    ...
    Next read: input a data item into variable; //update sentinel
}

 
while(temp != 999) //incorrect, temp was not initialized
{
    System.out.print("Enter a temperature(999 to stop) ";
    temp = input.nextDouble();
    sum = sum + temp;
    ... ...
}

 
System.out.print("Enter a temperature(999 to stop) ";
temp = input.nextDouble(); // CORRECT, priming read before loop
while(temp != 999) //test sentinel
{
    System.out.print("Enter a temperature (999 to stop) ";
    temp = input.nextDouble(); //incorrect, next read should be at the end of the loop
    sum = sum + temp;
    ... ...
}

 
System.out.print("Enter a temperature(999 to stop) ";
temp = input.nextDouble(); // CORRECT, priming read before loop
while(temp != 999) //test sentinel
{
    ...  ...
    sum = sum + temp;
    ...  ...
    System.out.print("Enter a temperature(999 to stop) ";
    temp = input.nextDouble(); //CORRECT, next read at the end of the loop
}

// Sentinel-controlled loop
import java.util.Scanner;

class Temp_Sentinel_2 {
    public static final int SENTINEL = 999;
    public static void main(String[] args){
        //Declarations
        Scanner input = new Scanner(System.in);
        double temp;
        double sum = 0;
        double avg;
        int count = 0;
        System.out.print("Enter a temperature(" + SENTINEL + " to stop): ");
        temp = input.nextDouble(); //priming read
        while (temp != SENTINEL)   //test sentinel
        {
            sum = sum + temp;
            count = count + 1;
            System.out.print("Enter a temperature(" + SENTINEL + " to stop): ");
            temp = input.nextDouble(); //next read
        }
        if(count != 0) {
            avg = sum / count;
            System.out.printf("\nThe average temperature is: %6.2f", avg);
            System.out.println();
        }
        else
            System.out.println("ERROR! NO input, NO output!!!");
    }
}

SAMPLE OUTPUT:
FIRST RUN:
Enter a temperature(999 to stop): 999
ERROR! NO input, NO output!!!
SECOND RUN:
Enter a temperature(999 to stop): 87
Enter a temperature(999 to stop): 86
Enter a temperature(999 to stop): 79
Enter a temperature(999 to stop): 58
Enter a temperature(999 to stop): 69
Enter a temperature(999 to stop): 94
Enter a temperature(999 to stop): 87
Enter a temperature(999 to stop): 91
Enter a temperature(999 to stop): 999
The average temperature is:  81.38
 

1. Initialize a flag (to true or false). Make sure that you use a meaningful name for the flag
2. Test the flag in the loop test expression.
3. Update: A condition in the loop body changes the value of the flag (to
false or true)

 
boolean found = false;
while(!found)
{
    ...
    ...
    if(expression)
        found = true;
    ...
}

// Flag-controlled loop
import java.util.Scanner;

class Temp_Flag {
    public static void main(String[] args){
        //Declarations
        Scanner input = new Scanner(System.in);
        double temp;
        double sum = 0;
        double avg;
        int count = 0;
        boolean isSafe = true; //initialize flag
        while (isSafe)   //test flag
        {
            System.out.print("Enter a temperature(>= 200 to stop): ");
            temp = input.nextDouble();
            if (temp >=  200)
                isSafe = false; //update flag
            else {
                sum = sum + temp;
                count = count + 1;
            }
        }
        if(count != 0) {
            avg = sum / count;
            System.out.printf("\nThe average temperature is: %6.2f", avg);
            System.out.println();
        }
        else
            System.out.println("ERROR! NO input, NO output!!!");
    }
}

SAMPLE OUTPUT:
FIRST RUN:
Enter a temperature(>= 200 to stop): 999
ERROR! NO input, NO output!!!
SECOND RUN:
Enter a temperature(>= 200 to stop): 78
Enter a temperature(>= 200 to stop): 89
Enter a temperature(>= 200 to stop): 80
Enter a temperature(>= 200 to stop): 77
Enter a temperature(>= 200 to stop): 67
Enter a temperature(>= 200 to stop): 85
Enter a temperature(>= 200 to stop): 333
The average temperature is:  79.33
 

          // Flag-controlled loop

import java.util.Scanner;

class Flag_Negative {
    public static void main(String[] args){
       //Declarations
        Scanner input = new Scanner(System.in);
        boolean nonNegative;
        int sum = 0;
        int number;
        nonNegative = true; //initialize flag
        while (nonNegative) { //test flag: default test done for true
            System.out.print("Enter a number(negative to stop) ");
            number = input.nextInt();
            if (number < 0)  //test the condition to change the flag
                nonNegative = false; //(reset)update flag
            else
                sum = sum + number;
        }
        System.out.println("\nThe sum of all positive #s is: " + sum);
    }
}

SAMPLE OUTPUT:
FIRST RUN:
Enter a number(negative to stop) -1
The sum of all positive #s is: 0
SECOND RUN:
Enter a number(negative to stop) 1
Enter a number(negative to stop) 2
Enter a number(negative to stop) 3
Enter a number(negative to stop) 4
Enter a number(negative to stop) 5
Enter a number(negative to stop) -1
The sum of all positive #s is: 15
 

 
a) Counting all data values: count the number of iterations in a loop by using an iteration counter (a counter variable that is incremented with each iteration). Note: the loop control variable of a counter-controlled loop is an iteration counter. However, not all iteration counters are loop control variables (See the example with the average temperature).
b) Counting special data values. Example: the sum of all odd (or even) numbers in a sequence of random numbers; the number of positive (or negative) numbers in a sequence of random numbers, etc. An event control has to be used.
c) Summing data values: you need an accumulator. Example:

 

Counter-controlled loop

Sentinel-controlled loop

import java.util.Scanner;
class Loop_Counter {
  public static void main(String[] args){
    //Declarations
    Scanner input = new Scanner(System.in); 
    int number, how_many;
    int sum = 0; 
    int count = 1; // initialize counter
    System.out.print("How many numbers in input? ");
    how_many = input.nextInt();
    while(how_many <=0) {//validate input
      System.out.print("\nERROR! Should be positive. Reenter: ");
      how_many = input.nextInt();
    }
    while (count <= how_many) { //test counter
      number = input.nextInt(); // input a value
      sum = sum + number; // update sum
      count++; // increment counter
    }
    System.out.println("Sum = " + sum);
  }
}
SAMPLE OUTPUT:
How many numbers in input? 5
1 2 3 4 5
Sum = 15
 
 
 
 
 
 

 

import java.util.Scanner;
class Loop_YesNo {
  public static void main(String[] args){
    //Declarations
    Scanner input = new Scanner(System.in); 
    int number;
    int sum = 0; 
    char ans;
    System.out.print("Input values and get the sum?(Y/N): ");
    ans = input.next().charAt(0); // priming read
    while (ans == 'Y' || ans == 'y') { //test sentinel
      System.out.print("Enter a number: ");
      number = input.nextInt(); // input a value
      sum = sum + number; // update sum
      System.out.print("\nDo you want to continue? (Y/N): ");
      ans = input.next().charAt(0); // next read
    }
    System.out.println("Sum = " + sum);
  }
}
SAMPLE OUTPUT:
FIRST RUN:
Input values and get the sum?(Y/N): n
Sum = 0
SECOND RUN:
Input values and get the sum?(Y/N): y
Enter a number: 1
Do you want to continue? (Y/N): )y
Enter a number: 2
Do you want to continue? (Y/N): )y
Enter a number: 3
Do you want to continue? (Y/N): )y
Enter a number: 4
Do you want to continue? (Y/N): )n
Sum = 10

Example 10: Count and sum the first ten odd numbers in a data set.

import java.util.Scanner;

class FirstTenOdd {
    public static final int MAX = 10;
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        int sum = 0;
        int count = 0;
        boolean flag = true; // initialize  flag
        int number;

        while (flag) // test flag
        {
            number = input.nextInt();
            if (number % 2 == 1) // test for odd number
            {
                count++;
                if (count <= MAX)
                    sum = sum + number;
                else
                    flag = false; // update  flag
            }
        }
        System.out.println("The sum of first " + MAX + " odd numbers is: " + sum);
    }
}

d) Keeping track of a previous and current value: when you need to remember the previous value of a variable.

4. How to Design Loops

1. What is the condition that ends the loop?
2. How should the condition be initialized?
3. How should the condition be updated?
4. What is the process being repeated?
5. How should the process be initialized?
6. How should the process be updated?
7. What is the state of the program when exiting the loop?

Where:

1 - 3  =  designing the flow control
4 - 6  =  processing within the loop
      7  =  the loop exit

1. Counter-Controlled Loops

2. Sentinel-Controlled Loops

3. EOF-Controlled Loops

4. Flag-Controlled Loops

5. Nested Loops

initialize outer loop
while(outer loop condition)
{
    . . .
    initialize inner loop
    while(inner loop condition)
    {
       . . .
       inner loop update
    }
    outer loop update
    . . .
}


Sample input:
 

  ID#      #Readings            ___            Actual readings
4567                   5           180   140   153   170   130
2318                   2                                      170   215
5232                   3                             150   151   145

Sample Output:
 

For patient ID#:  4567  average BP =   154.60
For patient ID#:  2318  average BP =   192.50
For patient ID#:  5232   average BP =  148.66
 
...
  ...
  ...
There were 432 patients.

The Algorithm:

 
1. Initialize  patientCount to 0
2. Get  first  patient ID
3. while patient ID not 0
      Get how many readings for this patient

 Increment patientCount
 use a count-controlled loop to read and sum up this patient’s howMany BP’s
 calculate average for patient

      Display ID and average for patient

 Get next patient ID

4. Display patientCount(how many patients)


The Java Program:
import java.util.Scanner;

class Medical {
    public static final int SENTINEL = 0;

    public static void main(String[] args){
       //Declarations
        Scanner input = new Scanner(System.in);
        int patientCount=0; // counter for the number of patients
        int thisID; // patient ID
        int howMany; // how many readings for patient
        int thisBP; // current blood pressure
        int totalForPatient;
        int count; // counter for inner loop
        double average; // average BP for patient
        System.out.print("Enter patient ID(" + SENTINEL + " to stop): ");
        thisID = input.nextInt(); // priming read for outer loop
        while(thisID != SENTINEL) // test sentinel (outer loop)
       {
            System.out.print("How many readings? ");
            howMany = input.nextInt();
            while(howMany <= 0) { //validate user input
                System.out.println("ERROR!!!Must be positive!");
                System.out.print(" How many readings? ");
                howMany = input.nextInt();
            }
            patientCount++;
            totalForPatient = 0;
            count = 0; // initialize inner loop counter
            while (count < howMany) // test counter (inner loop)
            {
                System.out.print("Enter reading for this patient: ");
                thisBP = input.nextInt();
                count++; //update inner loop counter
                totalForPatient = totalForPatient + thisBP;
            } //close inner loop
            average = totalForPatient / (double)(howMany);
            System.out.printf("For patient ID#: " + thisID + " average BP = %6.2f", average);
            System.out.print("\nEnter patient ID (" + SENTINEL + " to stop): ");
            thisID = input.nextInt(); // next read for outer loop
        } //close outer loop
        System.out.println(patientCount + " patients have been tested.\n");
    } //close main()
} //close class

SAMPLE OUTPUT:
FIRST RUN:
Enter patient ID(0 to stop): 0
0 patients have been tested.
SECOND RUN:
Enter patient ID(0 to stop): 12345
How many readings? 2
Enter reading for this patient: 132
Enter reading for this patient: 137
For patient ID#: 12345 average BP = 134.50
Enter patient ID(0 to stop): 12346
How many readings? 3
Enter reading for this patient: 144
Enter reading for this patient: 147
Enter reading for this patient: 160
For patient ID#: 12346 average BP = 150.33
Enter patient ID(0 to stop): 0
2 patients have been tested.

Program #1: Employee's weekly wages
// ***************************************************
//  Payroll program
//  This program computes each employee’s weekly wages
//  and the total company payroll
// ***************************************************
import java.util.Scanner;

class WeeklyWages {
    public static final double MAX_HOURS = 40.0; // Maximum normal hours
    public static final double OVERTIME = 1.5;   // Overtime pay factor
    public static final int SENTINEL = 0;

    public static void main(String[] args){
     //Declarations
        Scanner input = new Scanner(System.in);
        double     payRate; //  Employee’s pay rate
        double     hours;   //  Hours  worked
        double    wages;    //  Wages earned
        int       empNum;   //  Employee  ID  number
        double    total;    //  Total company payroll
        total = 0.0;
        System.out.print("Enter employee number: ");
        empNum = input.nextInt();  // priming read
        while (empNum != SENTINEL) // test sentinel
        {
            System.out.print("Enter pay rate: ");
            payRate = input.nextDouble();
            System.out.print("Enter hours worked: ");
            hours = input.nextDouble();
            if( hours > MAX_HOURS)
                wages = (MAX_HOURS * payRate ) + (hours - MAX_HOURS) * payRate * OVERTIME;
            else
                wages  =  hours * payRate;
            System.out.println("This week wages for the employee with ID " + empNum + " are $" + wages);
            total = total + wages;
            System.out.print("Enter employee number: ");
            empNum = input.nextInt();  // next read
        }
        System.out.println("\nTotal company payroll is: " + total);
   }
}

SAMPLE OUTPUT:
Enter employee number: 12345
Enter pay rate: 23.6
Enter hours worked: 44
This week wages for the employee with ID 12345 are $1085.6
Enter employee number: 12346
Enter pay rate: 32.7
Enter hours worked: 60
This week wages for the employee with ID 12346 are $2289.0
Enter employee number: 0
Total company payroll is: 3374.6

Program #2: Display the first 50 positive even integers five to a line.

import java.util.Scanner;
class Display {
    public static final int MAX_COUNT = 50;

    public static void main(String[] args){
        int n = 1;   // initialize
        while(n <= MAX_COUNT ) //test
        {
            System.out.printf("%6d", n * 2);
            // if n is divisible by 5, output a line feed.
            if (n % 5 == 0 )
                System.out.println();
            n++; // update
        }
    } //close main()
} //close class

SAMPLE OUTPUT:
     2     4     6     8    10
    12    14    16    18    20
    22    24    26    28    30
    32    34    36    38    40
    42    44    46    48    50
    52    54    56    58    60
    62    64    66    68    70
    72    74    76    78    80
    82    84    86    88    90
    92    94    96    98   100

Exercises:

  1. String example - use functions length()and charAt(). What is the output?

import java.util.Scanner;
class Display {
    public static void main(String[] args){
        //Declarations
        String name;
        int position = 0;
        Scanner input = new Scanner(System.in);
        System.out.print("Enter name: ");
        name = input.nextLine();
        while(position < name.length()) {
            System.out.println(name.charAt(position));
            position++;
        }
    }
}

  1. What is the output?

...
int limit = 5;
int j = 1;
while(j < limit) {
    if(j % 2 == 0)
        j++:
}

System.out.println("j = " + j);
 

  1. What is the output?

...
int m = 1;
int n = 3;
while(m < 15 && n < 20) {
    m = m + 1;
    n = n + 2;
}
System.out.println("The sum is " + (m + n));


References:
[1] Building Java Programs: A Back to Basics Approach, by Stuart Reges, and Marty Stepp, Addison Wesley, 2008.
[2] Java Programming: From Problem Analysis to Program Design, by D.S. Malik, Thomson Course Technology, 2008