稀疏数组经典例子——棋盘问题,当一个棋盘上面,落子比较少的时候,就会出现大面积的空白,浪费资源。
稀疏数组的概念,很简单 举个例子就可以说明:
原有棋盘:
00010
00200
00000
稀疏棋盘:
3 5 2 // 分别代表:总行数 总列数 总有效数据数
0 3 1 // 第一个有效数据的:所在行 所在列 值
1 2 2
现在用棋盘模拟,写一个案例:
约定:
用0代表无子
用1表示白子
用2表示黑子
普通数组转稀疏数组
思路分析
- 拿到原始棋盘数组之后,首先要分析这个棋盘的行数和列数,因为稀疏数组首先要存放的,就是行数和列数
- 再遍历得到所有有效数据的值(一步可以同时完成)
- 初始化创建稀疏数组
- 将原棋盘的值存入稀疏数组
各步骤代码实现:
第1、2步:
int sum = 0 ; // 总有效数据数
int rows = 0 ; // 总行数
int columns = 0 ; // 总列数
for (int[] row:chess) {
for (int data:row) {
if (data != 0) {
sum++;
}
columns++;
}
rows++;
}
columns = columns/rows; // 简单,想一想为啥要除
第3步
// 知道棋盘中有用数据个数之后,创建稀疏数组
int[][] SparseArray = new int[sum+1][3]; // 除了存放有效数据,还需要存放棋盘信息
SparseArray[0][0] = rows;
SparseArray[0][1] = columns;
SparseArray[0][2] = sum;
第4步
int count =1; // 计算是第几个有效数据
for (int i=0; i<rows ; i++) {
for (int j=0; j<columns ; j++) {
if (chess[i][j]!=0) {
SparseArray[count][0] = i;
SparseArray[count][1] = j;
SparseArray[count][2] = chess[i][j];
count++;
}
}
}
稀疏数组转回普通数组
很简单,直接放代码
// 将稀疏数组还原成最初的数组
int array[][] = new int[SparseArray[0][0]][SparseArray[0][1]]; // 初始化
for (int i=1 ; i<SparseArray[0][2]+1 ; i++){
// i从1开始是因为,稀疏数组第一行存放的是棋盘信息,而不是有效数据
// i<SparseArray[0][2]+1 因为i需要遍历到稀疏数组的最后一行,而有效数据个数就是最后一行的编号
// 如果是 i<SparseArray[0][2] 那么遍历到的最后一行其实是倒数第二行
// 出现这个情况的原因就在于 int[][] SparseArray = new int[sum+1][3] ,sum+1导致多出来一行
// +1 之后和之前遍历数组相比绕了一下
array[SparseArray[i][0]][SparseArray[i][1]] = SparseArray[i][2];
}