Chapter 3 · Data
Nested loops and 2D arrays
Step 1 of 18 · Concept
A loop inside a loop
A loop's block can hold another loop. The inner loop then runs all its rounds for each round of the outer loop.
for (int row = 1; row <= 2; row++) {
for (int col = 1; col <= 3; col++) {
System.out.print(row * col + " ");
}
System.out.println();
}
Rows and columns are the classic case: the outer loop goes down the rows, the inner loop along one row.
Step 2 of 18 · Quiz
How many rounds?
How many times does the inner block run?
for (int a = 1; a <= 4; a++) {
for (int b = 1; b <= 3; b++) {
System.out.print("*");
}
}
Step 3 of 18 · Demo
A multiplication table
Run it. %4d is a width, as in lesson 9: each number fills 4 columns, with spaces before it. So the columns
line up.
Step 4 of 18 · Try it
Try it: half a table
The inner loop's check can use the outer loop's variable. Change col <= 5 to col <= row, and run it: row 1
gets one number, row 5 gets five.
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
The inner loop's header is on line 4. Only its middle part, the check, changes.
Step 5 of 18 · Exercise
Your turn: a triangle of stars
Complete triangle: it prints n rows of *. Row 1 has one star, row 2 has two, and the last row has n. The
program must print:
*
**
*
**
***
It is the half table again, with a * instead of a number.
The outer loop counts row from 1 to n. The inner loop prints row stars with print; then println() ends
the row.
for (int row = 1; row <= n; row++) {
for (int i = 1; i <= row; i++) {
System.out.print("*");
}
System.out.println();
}
Step 6 of 18 · Concept
A grid is an array of arrays
int[][] grid = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
int[][] is an array whose cells hold arrows to arrays: a 2D array, or grid. Each row is an int[] of its
own. grid[1][2] takes row 1, then index 2 in it: 7.
Step 7 of 18 · Quiz
Find the cell
What is grid[2][1]?
int[][] grid = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
Step 8 of 18 · Concept
Rows and columns
| write | gives |
|---|---|
grid.length | the number of rows: 3 |
grid[0].length | the length of row 0: 4 columns |
new int[2][3] | a new grid of 2 rows and 3 columns, all 0 |
Every row of this grid is as long as row 0, so grid[0].length counts the columns.
Step 9 of 18 · Quiz
How many columns?
int[][] seats = new int[5][8]; What is seats[0].length?
Step 10 of 18 · Demo
A grid of numbers
Run it. The outer loop goes down the rows, the inner loop along one row.
Step 11 of 18 · Concept
One row, one column
You do not always need both loops.
- To walk along one row, keep its index fixed and loop over the columns:
grid[1][c]. - To walk down one column, keep its index fixed and loop over the rows:
grid[r][2].
Step 12 of 18 · Exercise
Your turn: row and column totals
sales holds four weeks (rows) of sales in three shops (columns). Complete rowTotal, which adds up one row,
and columnTotal, which adds up one column. The program must print:
Week 1: 10
Week 2: 10
Week 3: 11
Week 4: 6
Shop 1: 10
Shop 2: 14
Shop 3: 13
Each method needs one loop, not two: one index is given, the other one moves.
rowTotal keeps row and loops c over the columns. columnTotal keeps col and loops r over the rows.
int sum = 0;
for (int c = 0; c < grid[0].length; c++) {
sum += grid[row][c];
}
return sum;
Step 13 of 18 · Concept
A board of characters
A grid can hold any type. A tic-tac-toe board is a char[][] of 3 rows and 3 columns:
char[][] board = {
{'X', 'O', ' '},
{' ', 'X', ' '},
{'O', ' ', ' '}
};
'X'and'O'are the players' marks;' ', a space, is an empty square.- A move stores a mark in a square:
board[2][2] = 'X';.
Step 14 of 18 · Quiz
Which square?
On the board of 3 rows and 3 columns, which square does board[2][2] = 'X'; take?
Step 15 of 18 · Demo
A board from a 2D array
Run it. print draws a | between the squares of a row, and a line of -+-+- between the rows.
Step 16 of 18 · Check yourself
Check yourself: three in a row
Write the two methods, each as its comment says. The program must print exactly:
X wins
O wins
X wins
X wins
No winner
Count a row as a win until one of its squares is not mark. On one diagonal the row and column indexes are equal;
on the other they add up to 2.
Step 17 of 18 · Challenge · optional
Challenge: rows of their own length
Optional. It earns the lesson's third star.
Each row of a grid is an array of its own, so rows can have different lengths. This program sums each row of
scores, but it crashes. Fix it so that it prints:
Row 0: 16
Row 1: 4
Row 2: 24
Run it and read the trace. Row 1 has one element, but the inner loop asks for two: scores[0].length is 2.
Each row knows its own length. Row r's is scores[r].length.
Step 18 of 18 · Recap
Recap
- The inner loop runs all its rounds for each round of the outer loop.
- A 2D array holds arrows to row arrays.
grid[r][c]is rowr, columnc. grid.lengthcounts the rows;grid[0].lengthcounts the columns.- To walk one row, keep
rfixed. To walk one column, keepcfixed.
Next: lesson 12 adds Java's ready-made Math methods, and a method that calls itself.
Review
4 questions from this lesson, in a new order each time. Answer from memory: 3 of 4 right on the first try passes. On a day after you finish the lesson, a pass earns 15 XP.
The review needs JavaScript.
public class Table {
public static void main(String[] args) {
for (int row = 1; row <= 5; row++) {
for (int col = 1; col <= 5; col++) {
System.out.printf("%4d", row * col);
}
System.out.println();
}
}
}
public class Table {
public static void main(String[] args) {
for (int row = 1; row <= 5; row++) {
for (int col = 1; col <= 5; col++) {
System.out.printf("%4d", row * col);
}
System.out.println();
}
}
}
public class Triangle {
static void triangle(int n) {
// n rows; row 1 has one *, row n has n
}
public static void main(String[] args) {
triangle(2);
System.out.println();
triangle(3);
}
}
public class Grid {
public static void main(String[] args) {
int[][] grid = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
System.out.println("Rows: " + grid.length);
System.out.println("Columns: " + grid[0].length);
System.out.println("Row 1, column 2: " + grid[1][2]);
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[0].length; c++) {
System.out.printf("%4d", grid[r][c]);
}
System.out.println();
}
int[][] empty = new int[2][3];
System.out.print(empty.length + " rows of ");
System.out.println(empty[0].length + " zeros");
}
}
public class Totals {
// the sum of the numbers in one row
static int rowTotal(int[][] grid, int row) {
return 0;
}
// the sum of the numbers in one column
static int columnTotal(int[][] grid, int col) {
return 0;
}
public static void main(String[] args) {
int[][] sales = {
{3, 5, 2},
{4, 0, 6},
{1, 7, 3},
{2, 2, 2}
};
for (int r = 0; r < sales.length; r++) {
int week = r + 1;
int total = rowTotal(sales, r);
System.out.println("Week " + week + ": " + total);
}
for (int c = 0; c < sales[0].length; c++) {
int shop = c + 1;
int total = columnTotal(sales, c);
System.out.println("Shop " + shop + ": " + total);
}
}
}
public class Board {
static void print(char[][] board) {
for (int r = 0; r < board.length; r++) {
for (int c = 0; c < board[0].length; c++) {
System.out.print(board[r][c]);
if (c < board[0].length - 1) {
System.out.print("|");
}
}
System.out.println();
if (r < board.length - 1) {
System.out.println("-+-+-");
}
}
}
public static void main(String[] args) {
char[][] board = {
{'X', 'O', ' '},
{' ', 'X', ' '},
{'O', ' ', ' '}
};
board[2][2] = 'X';
print(board);
}
}
public class Winner {
// true when mark fills a whole row, a whole
// column, or one of the two diagonals
static boolean wins(char[][] board, char mark) {
return false;
}
// "X wins", "O wins" or "No winner"
static String result(char[][] board) {
return "";
}
public static void main(String[] args) {
char[][] a = {{'X', 'X', 'X'},
{'O', 'O', ' '},
{' ', ' ', ' '}};
char[][] b = {{'O', 'X', ' '},
{'O', 'X', ' '},
{'O', ' ', 'X'}};
char[][] c = {{'X', 'O', 'O'},
{' ', 'X', ' '},
{'O', ' ', 'X'}};
char[][] d = {{' ', 'O', 'X'},
{' ', 'X', 'O'},
{'X', ' ', 'O'}};
char[][] e = {{'X', 'O', 'X'},
{'X', 'O', 'O'},
{'O', 'X', 'X'}};
System.out.println(result(a));
System.out.println(result(b));
System.out.println(result(c));
System.out.println(result(d));
System.out.println(result(e));
}
}
public class Rows {
public static void main(String[] args) {
int[][] scores = {
{7, 9},
{4},
{8, 6, 10}
};
for (int r = 0; r < scores.length; r++) {
int sum = 0;
for (int c = 0; c < scores[0].length; c++) {
sum += scores[r][c];
}
System.out.println("Row " + r + ": " + sum);
}
}
}