简介

一维数组可以存储线性的元素集合,而二维数组则能够存储矩阵和表格。

二维数组的基本知识

二维数组的元素通过行和列的下标来访问。

声明二维数组变量并创建二维数组

声明二维数组的语法如下:

数据类型[][] 数组名;
或者
数据类型 数组名[][];

例如:

int[][] matrix;

或者

int matirx[][];

使用这个语法创建 5 x 5 的int型二维数组:

matrix = new int[5][5];

二维数组中使用两个下标,一个表示行,一个表示列。与一维数组一样,每个下标索引值都是 int 型的,从 0 开始。

注意: 使用 matrix[2,1]访问行下标为2、列下标为1的元素是一种长江错误。在 Java 中,每个下标必须放在一对方括号中。

也可以使用数组初始化来声明、创建和初始化一个二维数组:

int[][] array = {{1, 2, 3}, {2, 3, 4}, {3, 4, 5}};

获取二维数组的长度

二维数组实际上是一个数组,它的每个元素都是一个一维数组。数组 x 的长度是数组中元素的个数,可以用 x.length 获取该值。

锯齿数组

二维数组红的每一行本身就是一个数组,因此,各行的长度可以不同。这样的数组称为锯齿数组。

int[][] triangleArray = {
    {1, 2, 3, 4},
    {2, 4, 6},
    {3, 5}
};

处理二维数组

嵌套的for循环常用于处理二维数组。
假设如下创建数组 matrix:

int[][] matrix = new int[10][10];

使用输入值初始化二维数组

使用循环,实现用户输入值初始化数组:

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

使用随机值初始化二维数组

使用 0 到 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);
    }
}

打印二维数组

为打印一个二维数组,可以使用这种循环打印数组中的每个元素:

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

求所有元素的和

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

对数组按列求和

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);
}

求二维数组最大的一行和

使用变量 maxRow 和 indexOfMaxRow 分别跟踪和的最大值以及该行的索引值。

int maxRow = 0;
int indexOfMaxRow = 0;

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);
}

随机打乱

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);

        int temp = matrix[i][j];
        matrix[i][j] = matrix[i1][j1];
        matrix[i1][j1] = temp;
    }
}

实例练习:数独

public class CheckSudokuSolution {
    public static void main(String[] args) {

        //调用 readASolution() 读取数独表格
        int[][] grid = readASolution();

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

    //从控制台读取用户输入的答案
    public static int[][] readASolution() {

        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;
    }

    //检查答案是否有效
    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;
    }

    public static boolean isValid(int i, int j, int[][] grid) {

        //检查 grid[i][j] 在 i 行中是不是唯一的
        for(int column = 0; column < 9; column++)
            if(column != j && grid[i][column] == grid[i][j])
                return false;

        //检查 grid[i][j] 在 j 列中是否唯一
        for(int row = 0; row < 9; row++) 
            if(row != i && grid[row][j] == grid[i][j])
                return false;

        //检查 grid[i][j] 在 3 x 3 格中是否唯一
        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;
    }
}

多维数组

二维数组由一个一维数组的数组组成,而一个三维数组可以认为是由一个二维数组的数组所组成。

可以对二维数组变量的声明以及二维数组的创建方法进行推广,用于声明 >= 3 的 n 维数组变量和创建 n 维数组。

下述语法声明一个三维数组变量 scores:

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

实例学习:每日温度和湿度

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(Sytem.in);

        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;
        }

        for(int i = 0; i < NUMBER_OF_DAYS; i++) {
            double dailyTemperatureTotal = 0;
            double dailyHumidityTotal = 0;
            for(int j = 0; j < NUMBER_OF_HOURS; j++) {
                dailyTemperatureTotal += data[i][j][0];
                dailyHumidityTotal += data[i][j][1];
            }

            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);
        }
    }
}