Nested Loops
We can also put one loop inside of another loop – this is called nesting. We tend to want a nested loop when we want to:
Repeat a series of instructions
For each repetition, repeat a different series of instructionsIn a nested loop, the inner loop is completed (going through ALL its iterations) for each repetition of the outer loop.
Nested loop example: printing pattern #1
Nested loops can be tricky, so we’ll start off with two simple examples. Let’s say we want to print the following pattern:
* * * *
* * * *
* * * *
* * * *
* * * *Notice that we want 5 rows and 4 columns of stars (asterisks – above the 8 key). We will write a nested loop as if we were dealing with an array – the outer loop will step through each of the 5 rows, and the inner loop will step through each of the 4 columns. Inside the inner loop, we will print the next star (*):
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 4; j++) {
System.out.print("* ");
}
System.out.println();
}We are using the same trick with print statements that we did when printing a two dimensional array. The inner print statement is a print, because we are not done with the current row, and we want to print each row on a single line. The outer statement is a println, because we are done with the current row and want to advance to the next line for the next row.
Nested loop example: printing pattern #2
Let’s continue our printing example, but make it a bit more complicated. Suppose this is what we want to print now:
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4This is very similar to the previous example, except that we now want 5 rows and 5 columns. Also, instead of printing stars, we want to print numbers. Notice that in each case, the number printed is the same as the column number (0 is the leftmost column, then 1, etc.). So, we can change our solution to:
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
System.out.printf("%d ", j);
}
System.out.println();
}The only change to this solution is that we are printing out the value of j instead of a *. The
loop with j steps through the columns, so if we print j it will be the current column number.
And for each row, it will print 0, 1, 2, 3, 4 (because those are the values that j steps through).
Nested loop example: printing pattern #3
This is our third printing pattern, and let’s make it a little more complicated. Suppose now we want to print:
0
0 1
0 1 2 3
0 1 2 3 4We still want 5 rows, but the columns are a little different. We are still printing the current column number each time, but the number of columns varies with each row. Notice that row 0 has 1 column, row 1 has 2 columns, row 2 has 3 columns, row 3 has 4 columns, and row 4 has all 5 columns. So, the number of columns in each row is the row number + 1. In our for loops, i is keeping track of the current row number. So we can change our code as follows:
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < i+1; j++)
{
System.out.printf("%d ", j);
}
System.out.println();
}The only change to this solution is that the loop with j now steps while j < i+1. This controls
how many numbers we want to print on the current row, which we decided was the row number
plus one. The loop with i counts through the rows, so i+1 is how many elements we want to print on
the current row. (For the first row, i+1 will give us 1 column. For the second row, i+1 will
give us two columns, etc.)
Nested loop example: factoring a number
In this example, we want to ask the user for a number, and then print out its prime factors. (If the number is prime, then we want to print that fact instead.) For example, if the user enters 20, we want to print something like this:
20 = 2*2*5We know that we want to loop through possible factors (from 2 up to the number-1) and try seeing if they divide into the number evenly. The trick is that some values will be multiple factors – for example, we need to use 2 twice when factoring 20. So our approach will look something like this:
loop through all possible factors
factor out the current number as many times as possibleHere is a solution:
import java.util.*;
public class Factor
{
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
System.out.print("Enter a number to factor: ");
int num = s.nextInt();
System.out.printf("%d = ", num);
//We will divide factors out of cur as we find them
int cur = num;
//for each possible factor i
for (int i = 2; i <= num-1; i++)
{
//as long as i keeps dividing in evenly
while (cur % i == 0)
{
//print the factor and divide it out
System.out.printf("%d ", i);
cur = cur / i;
if (cur != 1) System.out.print("* ");
}
if (cur == num)
{
System.out.println("prime");
}
else
{
System.out.println();
}
}
}
}