Java学习笔记(8)Multidimensional Arrays

8.2.1 Declaring Variables of Two-Dimensional Arrays and Creating Two-Dimensional Arrays

// 二维数组声明

dataType[][] refVar;

// 创建二维数组

refVar = new dataType[10][10]; 

// 可以把上面的两步合成一步

dataType[][] refVar = new dataType[10][10];

// 另一种写法,不推荐

dataType refVar[][] = new dataType[10][10];

二维数组图解

声明、创建并初始化二维数组,可以合成一步,例如:

       equals to     


二维数组的长度属性

int[][] x = new int[3][4];

越界了,下标最大是3。Java会引发异常ArrayIndexOutOfBoundsException


8.2.3 Ragged Arrays锯齿数组

Java把二维数组设计为数组的数组,每一行的数组是独立的,并不要求长度相同,所以Java允许你构造一个锯齿数组:

int[][] matrix = {    

  {1, 2, 3, 4, 5},

  {2, 3, 4, 5},

  {3, 4, 5},

  {4, 5},

  {5}

};


锯齿数组图解

int[][] triangleArray = new int[5][];

triangleArray[0] = new int[5];

triangleArray[1] = new int[4];

triangleArray[2] = new int[3];

triangleArray[3] = new int[2];

triangleArray[4] = new int[1];

Note

The syntax new int[5][] for creating an array requires the first index to be specified.

The syntax new int[][] would be wrong.


8.3 Processing Two-Dimensional Arrays

The following are some examples of processing two-dimensional arrays.

1. 用输入值初始化数组

Initializing arrays with input values. The following loop initializes the array with user input values:

java.util.Scanner input = new Scanner(System.in);
System.out.println("Enter " + matrix.length + " rows and " +matrix[0].length + " columns: ");
for (int row = 0; row < matrix.length; row++) {
     for (int column = 0; column < matrix[row].length; column++) {
           matrix[row][column] = input.nextInt();
     }
}

2. 用随机值初始化数组

Initializing arrays with random values. The following loop initializes the array with random values between 0 and 99:

for (int row = 0; row < matrix.length; row++) {
    for (int column = 0; column < matrix[row].length; column++) {
        matrix[row][column] = (int)(Math.random() * 100);
    }
}

3. 打印数组

Printing arrays. To print a two-dimensional array, you have to print each element in the array using a loop like the following:

for (int row = 0; row < matrix.length; row++) {
    for (int column = 0; column < matrix[row].length; column++) {
        System.out.print(matrix[row][column] + " ");
    }
    System.out.println();
}

4. 数组求和

Summing all elements. Use a variable named total to store the sum. Initially total is 0. Add each element in the array to total using a loop like this:

int total = 0;
for (int row = 0; row < matrix.length; row++) {
    for (int column = 0; column < matrix[row].length; column++) {
        total += matrix[row][column];
    }
}

5. 数组按列求和

Summing elements by column. For each column, use a variable named total to store its sum. Add each element in the column to total using a loop like this:

for (int column = 0; column < matrix[0].length; column++) {
    int total = 0;
    for (int row = 0; row < matrix.length; row++)
        total += matrix[row][column];
    System.out.println("Sum for column " + column + " is " + total);
}

Which row has the largest sum? Use variables maxRow and indexOfMaxRow to track the largest sum and index of the row. For each row, compute its sum and update maxRow and indexOfMaxRow if the new sum is greater.

int maxRow = 0;
int indexOfMaxRow = 0;
// Get sum of the first row in maxRow
for (int column = 0; column < matrix[0].length; column++) {
    maxRow += matrix[0][column];
}
for (int row = 1; row < matrix.length; row++) {
    int totalOfThisRow = 0;
    for (int column = 0; column < matrix[row].length; column++)
        totalOfThisRow += matrix[row][column];
    if (totalOfThisRow > maxRow) {
        maxRow = totalOfThisRow;
        indexOfMaxRow = row;
    }
}
System.out.println("Row " + indexOfMaxRow + " has the maximum sum of " + maxRow);

6. 打散数组

Random shuffling. Shuffling the elements in a one-dimensional array was introduced in Section 7.2.6. How do you shuffle all the elements in a two-dimensional array? To accomplish this, for each element matrix[i][j], randomly generate indices i1 and j1 and swap matrix[i][j] with matrix[i1][j1], as follows:

for (int i = 0; i < matrix.length; i++) {
    for (int j = 0; j < matrix[i].length; j++) {
        int i1 = (int)(Math.random() * matrix.length);
        int j1 = (int)(Math.random() * matrix[i].length);
        // Swap matrix[i][j] with matrix[i1][j1]
        int temp = matrix[i][j];
        matrix[i][j] = matrix[i1][j1];
        matrix[i1][j1] = temp;
    }
}

8.4 Passing Two-Dimensional Arrays to Methods

public static int sum(int[][] m) {
	int total = 0;                                           
	for (int row = 0; row < m.length; row++)              
		for (int column = 0; column < m[row].length; column++) 
			total += m[row][column];   
	return total;                           
}

上述方法的形参是一个二维数组,因此调用此方法需要一个二维数组的实参,例如:

int[][] m = new int[3][4]; int total = sum(m);

例题:自动评卷

一份试卷有10题,8个学生参加考试,所有答卷存储在一个二维数组中,标准答案存储在一个一维数组中,写一个程序自动评卷。

 

public class GradeExam {
	/** Main method */
	public static void main(String[] args) {
		// Students' answers to the questions
		char[][] answers = {
				{ 'A', 'B', 'A', 'C', 'C', 'D', 'E', 'E', 'A', 'D' },
				{ 'D', 'B', 'A', 'B', 'C', 'A', 'E', 'E', 'A', 'D' },
				{ 'E', 'D', 'D', 'A', 'C', 'B', 'E', 'E', 'A', 'D' },
				{ 'C', 'B', 'A', 'E', 'D', 'C', 'E', 'E', 'A', 'D' },
				{ 'A', 'B', 'D', 'C', 'C', 'D', 'E', 'E', 'A', 'D' },
				{ 'B', 'B', 'E', 'C', 'C', 'D', 'E', 'E', 'A', 'D' },
				{ 'B', 'B', 'A', 'C', 'C', 'D', 'E', 'E', 'A', 'D' },
				{ 'E', 'B', 'E', 'C', 'C', 'D', 'E', 'E', 'A', 'D' } };

		// Key to the questions
		char[] keys = { 'D', 'B', 'D', 'C', 'C', 'D', 'A', 'E', 'A', 'D' };
		//Grade all answers
		for (int i = 0; i < answers.length; i++) {
			// Grade one student
			int correctCount = 0;
			for (int j = 0; j < answers[i].length; j++) {
				if (answers[i][j] == keys[j])
					correctCount++;
			}

			System.out.println("Student " + i + "'s correct count is "
					+ correctCount);
		}
	}
}

8.6 Case Study: Finding the Closest Pair

 

谈谈解题思路

首先,用一个二维数组存储所有点的坐标:double[][] points = new double[N][2]; 使用穷举法,计算每两个点的距离,然后找出它们的最小值。

穷举可以用二重循环,外循环从p1,p2,…pN,内循环从p1,p2,…pN,即可穷尽所有组合。考虑到距离的对称性,内循环只需要从外循环的下一个点开始计算。

LISTING 8.3 FindNearestPoints.java

import java.util.Scanner;
public class FindNearestPoints {
     public static void main(String[] args) {
          Scanner input = new Scanner(System.in);
          System.out.print("Enter the number of points: ");
          int numberOfPoints = input.nextInt();
          int numberOfPoints = input.nextInt();
          // Create an array to store points
          double[][] points = new double[numberOfPoints][2];
          System.out.print("Enter " + numberOfPoints + " points: ");
          for (int i = 0; i < points.length; i++) {
                points[i][0] = input.nextDouble();
                points[i][1] = input.nextDouble();
          }
          // p1 and p2 are the indices in the points' array
          int p1 = 0, p2 = 1; // Initial two points
          double shortestDistance = distance(points[p1][0], points[p1][1],
          points[p2][0], points[p2][1]); // Initialize shortestDistance
          // Compute distance for every two points
          for (int i = 0; i < points.length; i++) {
                for (int j = i + 1; j < points.length; j++) {
                     double distance = distance(points[i][0], points[i][1],
                     points[j][0], points[j][1]); // Find distance
                     if (shortestDistance > distance) {
                          p1 = i; // Update p1
                          p2 = j; // Update p2
                          shortestDistance = distance; // Update shortestDistance
                     }
                }
          }
          // Display result
         System.out.println("The closest two points are " + "(" + points[p1][0] + "," + points[p1][1] + ") and (" + points[p2][0] + ", " + points[p2][1] + 			")");
     }
     /** Compute the distance between two points (x1, y1) and (x2, y2)*/
     public static double distance(double x1, double y1, double x2, double y2) {
         return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
     }
}

8.7 Case Study: Sudoku

This section presents an interesting problem of a sort that appears in the newspaper every day. It is a number-placement puzzle, commonly known as Sudoku. This is a very challenging problem. To make it accessible to the novice, this section presents a simplified version of the Sudoku problem, which is to verify whether a Sudoku solution is correct. The complete program for finding a Sudoku solution is presented in Supplement VI.A. Sudoku is a 9 * 9 grid divided into smaller 3 * 3 boxes (also called regions or blocks), as shown in Figure 8.4a. Some cells, called fixed cells, are populated with numbers from 1 to 9. The objective is to fill the empty cells, also called free cells, with the numbers 1 to 9 so that every row, every column, and every 3 * 3 box contains the numbers 1 to 9, as shown in Figure 8.4b.

 

For convenience, we use value 0 to indicate a free cell, as shown in Figure 8.5a. The grid can be naturally represented using a two-dimensional array, as shown in Figure 8.5b.

 

To find a solution for the puzzle, we must replace each 0 in the grid with an appropriate number from 1 to 9. For the solution to the puzzle in Figure 8.5, the grid should be as shown in Figure 8.6.

Once a solution to a Sudoku puzzle is found, how do you verify that it is correct? Here are two approaches:

Check if every row has numbers from 1 to 9, every column has numbers from 1 to 9, and every small box has numbers from 1 to 9.

Check each cell. Each cell must be a number from 1 to 9 and the cell must be unique on every row, every column, and every small box.

 

FIGURE 8.6 A solution is stored in grid.

 

LISTING 8.4 CheckSudokuSolution.java

 import java.util.Scanner;

 public class CheckSudokuSolution {
	 public static void main(String[] args) {
		 // Read a Sudoku solution
		 int[][] grid = readASolution();

		 System.out.println(isValid(grid) ? "Valid solution" :
			 "Invalid solution");
	 }

	 /** Read a Sudoku solution from the console */
	 public static int[][] readASolution() {
		 // Create a Scanner
		 Scanner input = new Scanner(System.in);

		 System.out.println("Enter a Sudoku puzzle solution:");
		 int[][] grid = new int[9][9];
		 for (int i = 0; i < 9; i++)
			 for (int j = 0; j < 9; j++)
				 grid[i][j] = input.nextInt();

	 return grid;
	 }

	 /** Check whether a solution is valid */
	 public static boolean isValid(int[][] grid) {
		 for (int i = 0; i < 9; i++)
			 for (int j = 0; j < 9; j++)
				 if (grid[i][j] < 1 || grid[i][j] > 9
							 || !isValid(i, j, grid))
					 return false;
		 return true; // The solution is valid
	 }

	 /** Check whether grid[i][j] is valid in the grid */
	 public static boolean isValid(int i, int j, int[][] grid) {
		 // Check whether grid[i][j] is unique in i's row
		 for (int column = 0; column < 9; column++)
			 if (column != j && grid[i][column] == grid[i][j])
				 return false;

		 // Check whether grid[i][j] is unique in j's column
		 for (int row = 0; row < 9; row++)
			 if (row != i && grid[row][j] == grid[i][j])
				 return false;

		 // Check whether grid[i][j] is unique in the 3-by-3 box
		 for (int row = (i / 3) * 3; row < (i / 3) * 3 + 3; row++)
			 for (int col = (j / 3) * 3; col < (j / 3) * 3 + 3; col++)
				 if (row != i && col != j && grid[row][col] == grid[i][j])
					 return false;

	 	return true; // The current value at grid[i][j] is valid
	 }
}

The program invokes the readASolution() method (line 6) to read a Sudoku solution and return a two-dimensional array representing a Sudoku grid.

The isValid(grid) method checks whether the values in the grid are valid by verifying that each value is between 1 and 9 and that each value is valid in the grid (lines 27–34).

The isValid(i, j, grid) method checks whether the value at grid[i][j] is valid. It checks whether grid[i][j] appears more than once in row i (lines 39–41), in column j (lines 44–46), and in the 3 * 3 box (lines 49–52). 

How do you locate all the cells in the same box? For any grid[i][j], the starting cell of the 3 * 3 box that contains it is grid[(i / 3) * 3][(j / 3) * 3], as illustrated in

Figure 8.7.

 

With this observation, you can easily identify all the cells in the box. For instance, if grid[r][c] is the starting cell of a 3 * 3 box, the cells in the box can be traversed in a nested loop as follows:

// Get all cells in a 3-by-3 box starting at grid[r][c]

for (int row = r; row < r + 3; row++)

for (int col = c; col < c + 3; col++)

// grid[row][col] is in the box

It is cumbersome to enter 81 numbers from the console. When you test the program, you may store the input in a file, say CheckSudokuSolution.txt (see www.cs.armstrong.edu/liang/ data/CheckSudokuSolution.txt), and run the program using the following command:

java CheckSudokuSolution < CheckSudokuSolution.txt

8.8 Multidimensional Arrays

Java中多维数组的用法和二维数组差不多,依然是采用数组的数组这种技术来构造。例如一个三维数组可以这样声明和创建:

 double[][][] scores = new double[10][5][2];


8.8.1 Case Study: Daily Temperature and Humidity

 


LISTING 8.5 Weather.java

 import java.util.Scanner;

 public class Weather {
	 public static void main(String[] args) {
		 final int NUMBER_OF_DAYS = 10;
		 final int NUMBER_OF_HOURS = 24;
		 double[][][] data
 			= new double[NUMBER_OF_DAYS][NUMBER_OF_HOURS][2];

		 Scanner input = new Scanner(System.in);
		 // Read input using input redirection from a file
		 for (int k = 0; k < NUMBER_OF_DAYS * NUMBER_OF_HOURS; k++) {
			 int day = input.nextInt();
			 int hour = input.nextInt();
			 double temperature = input.nextDouble();
			 double humidity = input.nextDouble();
			 data[day - 1][hour - 1][0] = temperature;
			 data[day - 1][hour - 1][1] = humidity;
		 }

		 // Find the average daily temperature and humidity
		 for (int i = 0; i < NUMBER_OF_DAYS; i++) {
			 double dailyTemperatureTotal = 0, dailyHumidityTotal = 0;
			 for (int j = 0; j < NUMBER_OF_HOURS; j++) {
				 dailyTemperatureTotal += data[i][j][0];
				 dailyHumidityTotal += data[i][j][1];
			 }

			 // Display result
			 System.out.println("Day " + i + "'s average temperature is "
				 + dailyTemperatureTotal / NUMBER_OF_HOURS);
			 System.out.println("Day " + i + "'s average humidity is "
				 + dailyHumidityTotal / NUMBER_OF_HOURS);
		 }
	 }
}

 

Day 0's average temperature is 77.7708

Day 0's average humidity is 0.929583

Day 1's average temperature is 77.3125

Day 1's average humidity is 0.929583

. . .

Day 9's average temperature is 79.3542

Day 9's average humidity is 0.9125

 

You can use the following command to run the program:

java Weather < Weather.txt

 

8.8.2 Case Study: Guessing Birthdays例题:猜生日

还记得那些天我们一起猜过的生日吗?5张表格,依次提问,最后求和。现在,我们把表格存储在三维数组里,然后再猜一次。

 

import java.util.Scanner;
public class GuessBirthdayUsingArray {
	public static void main(String[] args) {
		int day = 0; // Day to be determined
		int answer;
		int[][][] dates = {
				{{ 1, 3, 5, 7 }, { 9, 11, 13, 15 }, { 17, 19, 21, 23 }, { 25, 27, 29, 31 }},
				{{ 2, 3, 6, 7 }, { 10, 11, 14, 15 }, { 18, 19, 22, 23 }, { 26, 27, 30, 31 }},
				{{ 4, 5, 6, 7 }, { 12, 13, 14, 15 }, { 20, 21, 22, 23 }, { 28, 29, 30, 31 }},
				{{ 8, 9, 10, 11 }, { 12, 13, 14, 15 }, { 24, 25, 26, 27 }, { 28, 29, 30, 31 }},
				{{ 16, 17, 18, 19 }, { 20, 21, 22, 23 }, { 24, 25, 26, 27 }, { 28, 29, 30, 31 }} 
		};
		Scanner input = new Scanner(System.in);
		for (int i = 0; i < 5; i++) {
			System.out.println("Is your birthday in Set" + (i + 1) + "?");
			for (int j = 0; j < 4; j++) {
				for (int k = 0; k < 4; k++)
					System.out.printf("%4d", dates[i][j][k]);	
				System.out.println();
			}
			System.out.print("\nEnter 0 for No and 1 for Yes: ");
			answer = input.nextInt();
			if (answer == 1)
				day += dates[i][0][0];
		}
		System.out.println("Your birthday is " + day);
	}
}

CHAPTER 3 SUMMARY

1. A two-dimensional array can be used to store a table.

2. A variable for two-dimensional arrays can be declared using the syntax: 

elementType[][] arrayVar.

3. A two-dimensional array can be created using the syntax:

new elementType [ROW_SIZE][COLUMN_SIZE].

4. Each element in a two-dimensional array is represented using the syntax:

arrayVar[rowIndex][columnIndex].

5. You can create and initialize a two-dimensional array using an array initializer with the syntax:

elementType[][] arrayVar = {{row values}, . . . , {row values}}.

6. You can use arrays of arrays to form multidimensional arrays. For example, a variable for three-dimensional arrays can be declared as elementType[][][] arrayVar, and a three-dimensional array can be created using new elementType[size1][size2][size3].

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值