稀疏数组介绍
当数组中大部分元素为0或者为同一值的时候,可以利用稀疏数组减少对存储资源的占用。稀疏数组只适用于数据稀疏的情况。当数组中存储的的数据过多的时候,存储在稀疏数组中的数据量,可能比原数组的中数据量还大,就不适用了。
稀疏数组工作原理
- 记录数组中一共有几行几列,一共有多少个有效元素。
- 稀疏数组一共三列,第一行第一列用来记录原始数组的行数,第一行第二列用来记录原始数组的列数,第一行第三列用来记录有几个有效元素。第二行及以后第一列记录有效元素所在行,第二列记录有效元素所在列,第三列记录有效元素的值。
二维数组转稀疏数组
- 遍历原始的二维数组,得到有效数据的个数
- 根据有效的数据个数创建稀疏数组sparseArray int[getTotalElements + 1][3]
- 将数组的有效数据存入到稀疏数组
稀疏数组转原始数组
- 先读取稀疏数组的第一行,根据第一行的数据, 创建原始的二维数组,比如上面的int[][] array = new int[sparseArray[0][0]][sparseArray[0][1]];
- 再读取稀疏数组第二行及第二行以后的数据,并赋给原始的二维数组
public class SparseArray {
public static void main(String[] args) {
int[][] array = generateArray(11, 11, 2, 3);
System.out.println("**********************初始化棋盘**************************************");
printArray(array);
int[][] sparseArray = generateSparse(array);
System.out.println("**********************稀疏数组**************************************");
printArray(sparseArray);
int[][] recoverArray = recoverArray(sparseArray);
System.out.println("**********************恢复后的棋盘**************************************");
printArray(recoverArray);
}
/**
* 根据稀疏数组还原原数组
* @param sparseArray
* @return
*/
public static int[][] recoverArray(int[][] sparseArray) {
if (null == sparseArray) {
return null;
}
int[][] array = new int[sparseArray[0][0]][sparseArray[0][1]];
for (int i = 1; i < sparseArray.length; i++) {
array[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
}
return array;
}
/**
* 根据棋盘和包含的棋子数量生成稀疏数组。
*
* @param array
* @return
*/
public static int[][] generateSparse(int[][] array) {
if (null == array) {
return null;
}
//创建稀疏数组。
int[][] sparseArray = new int[getTotalElements(array) + 1][3];
//给稀疏数组第一行赋值
sparseArray[0][0] = array.length;
sparseArray[0][1] = array[0].length;
sparseArray[0][2] = getTotalElements(array);
// 每一行代表一个棋子
int count = 0;
// 给稀疏数组赋值
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
if (array[i][j] > 0) {
count++;
sparseArray[count][0] = i;
sparseArray[count][1] = j;
sparseArray[count][2] = array[i][j];
}
}
}
return sparseArray;
}
/**
* 统计棋盘中一共有多少棋子,1代表黑子,2代表白子
*
* @param array
* @return
*/
public static int getTotalElements(int[][] array) {
int total = 0;
for (int[] row : array) {
for (int data : row) {
if (data > 0) {
total++;
}
}
}
return total;
}
/**
* 初始化一个x乘y二维数组:0:无子, 1:黑子, 2:白子。
*
* @param x 行
* @param y 列
* @param black 黑子数量,1表示黑子
* @param white 白子数量,2表示白子
* @return
*/
public static int[][] generateArray(int x, int y, int black, int white) {
//初始化二维数组代表棋盘
int[][] chessArray = new int[x][y];
//初始化黑子
for (int i = 0; i < black; i++) {
chessArray[getRandom(x)][getRandom(y)] = 1;
}
//初始化白子
for (int j = 0; j < white; j++) {
chessArray[getRandom(x)][getRandom(y)] = 2;
}
return chessArray;
}
/**
* 生成小于i的整型随机数
*
* @param i
* @return
*/
public static int getRandom(int i) {
return (int) (Math.random() * i);
}
/**
* 输出二维数组
*
* @param array
*/
public static void printArray(int[][] array) {
//输出二维数组
for (int[] row : array) {
for (int data : row) {
System.out.printf("%d\t", data);
}
System.out.println();
}
}
}
运行结果:
**********************初始化棋盘**************************************
0 0 0 0 0 0 0 2 0 0 0
0 0 0 2 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 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 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
**********************稀疏数组**************************************
11 11 5
0 7 2
1 3 2
1 9 1
7 9 2
9 6 1
**********************恢复后的棋盘**************************************
0 0 0 0 0 0 0 2 0 0 0
0 0 0 2 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 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 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