稀疏数组 SparseArray
1. 案例分析
- 稀疏数组和二维数组,使两种数据结构可以轻松的转换,
从而实现五子棋程序中有存盘和续上盘的功能。
- 规约:棋盘没有放棋子为0,白子为1,黑子为2
- 当一个二维数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
- 下面是稀疏数组储存数据的结构:
- 记录数组 一共有几行几列,有多少个不同的值
- 把具有不同值的元素的行列及值记录在一个小规模的数组中-
2. 代码实现
接下来我们通过Java代码来完成二维数组与稀疏数组之间的转换。
我们首先需要知道:
在二维数组中数组名.length指示数组的行数,数组名[行下标] .length指示该行中的元素个数。
我们把二维数组转换成稀疏数组,并且储存到
map.data
中,再通过Java中Io流读取文件进行复原。
2.1 二维数组转存为稀疏数组
- 首先我们创建一个11*11的二维数组(五子棋棋盘)
- 在二维数组里面,0 1 2 分别表示 没有放棋子 黑子 白子
- 遍历二维数组,显示原始的棋盘布局
- 我们首先通过遍历二维数组,获得棋子的个数sum
- 根据已知的棋子数,创建稀疏数组
int[][] sparseArr = new int[sum+1][3];
- 进行赋值:根据上图结合着稀疏数组的结构品味~~
- 遍历二维数组,将非零值放到sparseArr中,下面是二维数组转稀疏数组的核心逻辑~~
- 输出稀疏数组的形式,并且存盘(即通过IO流把稀疏数组保存到硬盘中)
public class SparseArrayOut{
//创建一个main方法,用来实现五子棋(二维数组转存为稀疏数组)
public static void main(String[] args) throws IOException{
//第一步:创建一个11*11的二维数组(五子棋棋盘)
int[][] array = new int[11][11];
//在二维数组里面,0 1 2 分别表示 没有放棋子 黑子 白子
array[2][1] = 1;
array[2][3] = 2;
array[4][5] = 2;
//遍历二维数组,显示原始的棋盘布局
System.out.println("原始的二维数组");
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
System.out.print(array[i][j]);
}
System.out.println();
}
//将二维数组转成稀疏数组,首先遍历数组获得值不为0的个数
int sum = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if(array[i][j]!=0) {
//sum就是value[0]的值
sum++;
}
}
}
//得到棋子的数量
System.out.println("这局共有"+sum+"个棋子");
//根据已知的棋子数,创建稀疏数组
int[][] sparseArr = new int[sum+1][3];
//给稀疏数组赋值
sparseArr[0][0] = 11;
sparseArr[0][1] = 11;
sparseArr[0][2] = sum;
//遍历二维数组,将非零值放到sparseArr中
int count = 0;//用于记录是第几个非0数据,即是索引
for (int i = 0; i <array.length; i++) {
for (int j = 0; j < array.length; j++) {
if(array[i][j]!=0) {
//这一段是?
count++;
sparseArr[count][0]=i;
sparseArr[count][1]=j;
sparseArr[count][2]=array[i][j];
}
}
}
//输出稀疏数组的形式,并且存盘
System.out.println("得到稀疏数组为......");
File file = new File("E:/file/","map.data");
FileOutputStream fos = new FileOutputStream(file);
for (int i = 0; i < sparseArr.length; i++) {
// %d 打印十进制整数
// \t 横向制表符
// \n 换行
System.out.printf("%d\t%d\t%d\t\n",sparseArr[i][0],sparseArr[i][1],sparseArr[i][2]);
fos.write(sparseArr[i][0]);
fos.write(sparseArr[i][1]);
fos.write(sparseArr[i][2]);
}
fos.close();
System.out.println();
}
}
2.2 从map.data
中读取数据,并将其还原成二维数组
- 先读取稀疏数组的第一行,根据第一行新建数组
- 读取稀疏数组后几行数据
- 最后输出恢复后的数据
public class SparseArrayIn{
//创建一个main方法,用来实现五子棋
public static void main(String[] args) throws IOException{
File file = new File("E:/file/","map.data");
FileInputStream fis = new FileInputStream(file);
int row = fis.read();
int col = fis.read();
int value = fis.read();
//1.先读取稀疏数组的第一行,根据第一行新建数组
int[][] array2 = new int[row][col];
//2.读取稀疏数组后几行数据
for (int i = 1; i <= value; i++) {
int rows = fis.read();
int cols = fis.read();
int values = fis.read();
array2[rows][cols]=values;
}
fis.close();
//输出恢复后的数据
System.out.println("恢复后的二维数组");
for (int[] rowss : array2) {
for (int data : rowss) {
System.out.printf("%d\t",data);
}
System.out.println();
}
}
}