**引言**
本人是一个Java爱好者,正在学习Java的数据结构与算法,记录一下自己的学习思路,
有需要的小伙伴们可以参考一下,不足的地方欢迎指正:
首先我们来看一个案例:
[以五子棋 存档退出和继续上盘的功能分析为例]
我们可以考虑使用普通的二维数组来保存棋局0代表无子,1代表黑子,2代表蓝子,那么二维数组为:
使用原始的二维数组固然可以保存棋局,但是存在一个问题,数组中大量的元素都是0,无意义的数据,那么我们的稀疏数组派上用场了
我们可以将此二维数组转化为稀疏数组再保存到本地文件,可以节省空间,当我们需要使用的时候在还原为二维数组
**稀疏数组的特点:
1.稀疏数组固定三列
2.第一行的元素存储原数组的总行数列数以及除0以外其他值的个数
3.其他行用来存储非0值所在的原始数组的行列信息以及值信息**
下面我们来整理一下实现**存盘退出**和**继续上盘**的思路:
1.[存盘退出]:就是将棋盘数据持久化到本地文件,我们可以这样做:
**棋盘-->二维数组-->稀疏数组[压缩]--->序列化到本地文件**
2.[续上盘]: 就是将本地文件中的稀疏数组还原为棋盘,我们可以这样做:
**读取本地文件-->[得到]稀疏数组-->[还原]二维数组-->还原棋盘**
[参考文档](https://mermaid-js.github.io/mermaid/#/flowchart?id=graph)
好了,思路就分析到这里了,接下来我们上代码:
public class SparseArrayTest {
public static void main(String[] args) {
// 1.创建和初始化原始二维数组
int[][] oldArray = new int[11][11];
// 2.根据棋盘为二维数组中的元素赋值
oldArray[1][2] = 1;
oldArray[2][3] = 2;
// 3.将二维数组转化为稀疏数组
int[][] sparseArray = parseToSparseArray(oldArray);
// 4.将稀疏数组序列化到文件中
saveSparseArrayToFile(sparseArray);
// 5.读取文件 得到稀疏数组
int[][] arraySparse = readSparseArrayFromLocalFile("array_save.txt");
// 6.将稀疏数组还原为二维数组
int[][] oldArray2 = restoreArrayBySparseArray(arraySparse);
// 7.分别遍历原二维数组、稀疏数组、还原后的二维数组验证结果:
System.out.println("原数组");
printArray(oldArray);
System.out.println("稀疏数组");
printArray(arraySparse);
System.out.println("还原的二维数组");
printArray(oldArray2);
}
}
/*
将二维数组转化为稀疏数组
*/
private static int[][] parseToSparseArray(int[][] oldArray) {
int count = 0;//存储原二维数组的特殊值个数
int row = 0;//记录原二维数组外层数组的长度
int col = 0;//记录原二维数组内层数组的长度
for (int i = 0; i < oldArray.length; i++) {
row++;
for (int j = 0; j < oldArray[i].length; j++) {
col++;
if (oldArray[i][j] != 0) {
count++;
}
}
}
// 创建稀疏数组
int[][] sparseArray = new int[count + 1][3];
// 稀疏数组第一个位置用来记录原数组的信息
sparseArray[0] = new int[] { row, col / row, count };
int k = 1;//记录稀疏数组的下标从1开始
//遍历原数组 为稀疏数组的元素赋值
for (int i = 0; i < oldArray.length; i++) {
for (int j = 0; j < oldArray[i].length; j++) {
if (oldArray[i][j] != 0) {
sparseArray[k++] = new int[] { i, j, oldArray[i][j] };
}
}
}
//得到稀疏数组
return sparseArray;
}
/*
将稀疏数组序列化到文件中
*/
private static void saveSparseArrayToFile(int[][] sparseArray) {
ObjectOutputStream outputStream = null;
try {
//创建流
outputStream = new ObjectOutputStream(new FileOutputStream(new File("array_save.txt")));
// 写入文件
outputStream.writeObject(sparseArray);
System.out.println("保存成功");
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭流
try {
if (outputStream != null)
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
从本地文件中读取稀疏数组
*/
private static int[][] readSparseArrayFromLocalFile(String path) {
ObjectInputStream inputStream = null;
try {
//创建读入流
inputStream = new ObjectInputStream(new FileInputStream(new File(path)));
//读取文件
return (int[][]) inputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
//关闭流
try {
if (inputStream != null)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
将稀疏数组还原为二维数组
*/
private static int[][] restoreArrayBySparseArray(int[][] arraySparse) {
int[][] array = new int[arraySparse[0][0]][arraySparse[0][1]];
for (int i = 1; i < arraySparse.length; i++) {
array[arraySparse[i][0]][arraySparse[i][1]] = arraySparse[i][2];
}
return array;
}
/*
打印数组
*/
private static void printArray(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();
}
}