一、需求场景
在围棋或者五子棋对战中,如果要保存游戏进度,可以使用一个二维数组保存棋子位置,结果如图所示:
比如,我们可以将棋盘进行抽象化,用一个 15 × 15 的二维数组来表示,然后用 0 表示空点,用 1 表示白子,用 2 表示黑子,于是就可以抽象为如上模样。
这样的一个15 x 15的棋盘总共要存225个元素,但是有大量的重复数据,比如0,
这样就造成了空间浪费。
我们可以使用一个稀疏数组来存储这个棋盘。
二、介绍
当一个数组大部分元素是0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组
处理方法:
1、记录数组一共有几行几列,有多少个不同的值
2、把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
三、代码实现
/**
- 二维数组与稀疏数组
*/
public class SparseArrayTest {
public static void main(String[] args) {
// 用二维数组保存棋盘
int[][] arr = saveChess();
// 打印二维数组
print(arr);
// 将二维数组转化为稀疏数组
int[][] sparseArr = castSparseArray(arr);
// 打印稀疏数组
print(sparseArr);
// 稀疏数组转二位数组
int[][] arr2 = castToArray(sparseArr);
print(arr2);
}
/**
* 打印普通数组
*/
public static void print(int[][] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + "\t");
}
System.out.println();
}
System.out.println("--------------------------------------");
}
/**
* 将棋盘数据保存为二维数组
*/
public static int[][] saveChess() {
// 初始化棋盘(大小为 15 * 15)
int[][] arr = new int[15][15];
// 保存白子(用1表示)
arr[5][5] = 1;
arr[7][5] = 1;
arr[6][7] = 1;
// 保存黑子(用2表示)
arr[6][6] = 2;
arr[7][6] = 2;
arr[8][6] = 2;
arr[7][7] = 2;
return arr;
}
/**
* 普通数组转稀疏数组
*
* @param arr_普通数组
* @return 稀疏数组
*/
public static int[][] castSparseArray(int[][] arr) {
// 原数组的总行数
int row = arr.length;
// 原数组的总列数
int cloumn = arr[0].length;
// 获取黑白子总数
int sum = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
if (arr[i][j] != 0) {
sum++;
}
}
}
// 创建稀疏数组(sum+1 行表示 sum 个黑白子 + 1行规模)
int[][] sparseArray = new int[sum + 1][3];
// 第 1 行原二维数组的行、列、棋子总数
sparseArray[0][0] = row;
sparseArray[0][1] = cloumn;
sparseArray[0][2] = sum;
// 第 2 行开始存具体数据(每行都是一个棋子数据)
int sparseRow = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
if (arr[i][j] != 0) {
sparseRow++;
sparseArray[sparseRow][0] = i;
sparseArray[sparseRow][1] = j;
sparseArray[sparseRow][2] = arr[i][j];
}
}
}
return sparseArray;
}
/**
* 稀疏数组转普通数组
*
* @param sparseArr_稀疏数组
* @return 普通二维数组
*/
public static int[][] castToArray(int[][] sparseArr) {
// 获取稀疏数组第 1 行(记录了原数组的总行数和总列数)
int[] rowFirst = sparseArr[0];
// 初始化数组(棋盘)
int row = rowFirst[0];
int column = rowFirst[1];
int[][] arr = new int[row][column];
// 初始化数据(黑白子)
for (int i = 1; i < sparseArr.length; i++) {
int[] sparseRow = sparseArr[i];
arr[sparseRow[0]][sparseRow[1]] = sparseRow[2];
}
return arr;
}
}
四、总结
在存储数组数据的时候,我们如果存在许多默认值的数据,不妨用稀疏数组来进行存储,这样数据相对来说就会瘦小很多,不但可以节省磁盘空间,还可以优化磁盘读写时性能。