先看一个实际需求
- 实现一个五子棋程序,拥有存盘退出和续上盘的功能
- 分析问题
在Java中,可以使用二维数组实现记录棋盘的功能。
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 2 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
但是像上图这种情况,由于二维数组中默认值是0,所以记录了很多没有意义的数据,造成了空间的浪费,这个时候就可以使用稀疏数组来存储棋盘数据了。
稀疏数组
基本介绍
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法是:
- 记录数组一共有几行几列,有多少个不同的值
- 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
稀疏数组举例说明
实现思路
- 二维数组转稀疏数组的思路
- 遍历原始的二维数组,得到有效数据的个数sum
- 根据sum就可以创建稀疏数组sparseArray = int [sum+1] [3]
- 将二维数组的有效数据存入到稀疏数组
- 稀疏数组转新的二维数组的思路
- 先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的
chessArray2 = int [15] [15] - 再读取稀疏数组后几行的数据,并赋值给原始的二维数组即可
代码实现
public class SparseArray {
public static void main(String[] args) {
// 设置一个初始的空棋盘
int[][] arr = new int[15][15];
// 1:代表黑子
arr[2][3] = 1;
// 2:代表白子
arr[3][4] = 2;
System.out.println("打印原始棋盘的二维数组:");
for (int[] ints : arr) {
for (int anInt : ints) {
System.out.printf("%d\t", anInt);
}
System.out.println();
}
System.out.println();
System.out.println("分割线======================================》");
System.out.println();
/*
* 二维数组转稀疏数组
*/
// 遍历原始的二维数组,得到有效数据的个数sum
int sum = 0;
for (int[] ints : arr) {
for (int anInt : ints) {
if (anInt != 0) {
sum++;
}
}
}
System.out.println("原始的二维数组的有效数据个数=" + sum);
// 根据sum就可以创建稀疏数组sparseArray = int [sum+1] [3]
int[][] sparseArray = new int[sum + 1][3];
// 稀疏数组第一行记录原始数组的行数、列数、有效数据的个数
sparseArray[0][0] = arr.length;
sparseArray[0][1] = arr[0].length;
sparseArray[0][2] = sum;
// 将二维数组的有效数据存入到稀疏数组
// 稀疏数组的从第二行开始记录
int count = 1;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[0].length; j++) {
int value = arr[i][j];
if (value != 0) {
sparseArray[count][0] = i;
sparseArray[count][1] = j;
sparseArray[count][2] = value;
count++;
}
}
}
System.out.println("打印转换后得到的稀疏数组:");
for (int[] ints : sparseArray) {
for (int anInt : ints) {
System.out.printf("%d\t", anInt);
}
System.out.println();
}
System.out.println();
System.out.println("分割线======================================》");
System.out.println();
/*
* 稀疏数组转换成新的二维数组
*/
// 获取新二维数组的行数
int rowLength = sparseArray[0][0];
// 获取新二维数组的列数
int colLength = sparseArray[0][1];
int[][] newArr = new int[rowLength][colLength];
for (int i = 1; i < sparseArray.length; i++) {
newArr[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
}
System.out.println("打印新棋盘的二维数组:");
for (int[] ints : newArr) {
for (int anInt : ints) {
System.out.printf("%d\t", anInt);
}
System.out.println();
}
}
}
控制台打印结果如下:
打印原始棋盘的二维数组:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 2 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
分割线======================================》
原始的二维数组的有效数据个数=2
打印转换后得到的稀疏数组:
15 15 2
2 3 1
3 4 2
分割线======================================》
打印新棋盘的二维数组:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 2 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0