Java学习笔记(8)Multidimensional Arrays

来源:互联网 发布:淘宝天下 诈骗 编辑:程序博客网 时间:2024/05/20 07:49

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 between0 and99:

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 namedtotal to store the sum. Initiallytotal is 0. Add each element in the array tototal 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 namedtotal to store its sum. Add each element in the column tototal 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 variablesmaxRow andindexOfMaxRow to track the largest sum and index of the row. For each row, compute its sum and updatemaxRow andindexOfMaxRow if the new sum is greater.

int maxRow = 0;int indexOfMaxRow = 0;// Get sum of the first row in maxRowfor (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 elementmatrix[i][j], randomly generate indicesi1 and j1and 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 questionschar[][] 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 questionschar[] keys = { 'D', 'B', 'D', 'C', 'C', 'D', 'A', 'E', 'A', 'D' };//Grade all answersfor (int i = 0; i < answers.length; i++) {// Grade one studentint 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 asSudoku. 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 calledregions orblocks), as shown in Figure 8.4a. Some cells, calledfixed cells, are populated with numbers from1 to9. The objective is to fill the empty cells, also calledfree cells, with the numbers1 to9 so that every row, every column, and every 3* 3 box contains the numbers1 to9, 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 ingrid.

 

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 between1 and9 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 whethergrid[i][j] appears more than once in rowi (lines 39–41), in columnj (lines 44–46), and in the 3* 3 box (lines 49–52). 

How do you locate all the cells in the same box? For anygrid[i][j], the starting cell of the 3* 3 box that contains it isgrid[(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 (introw = r; row < r + 3; row++)

for (intcol = 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, sayCheckSudokuSolution.txt (seewww.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 determinedint 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].

0 0
原创粉丝点击