数据结构与算法
简单的做一下学习笔记
五子棋保存与恢复
跟朋友一起下五子棋,刚下两步,突然有事要出门,怎么办呢?
只能暂时把棋盘锁起来,不让熊孩子碰到。但是这样太麻烦,万一熊孩子把锁打开了呢。
所以,我想到了一个办法,用数组的方式记录下来下到哪了,回来时候用数组恢复棋盘。
这样再也不用担心熊孩子捣乱了。
首先,棋盘是这个样子的:
————————————————————————————
| 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 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 0 0 0 0 0 0 0 0 0 0 |
| 0 0 0 0 0 0 0 1 1 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 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 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 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
——————————————————————————————
是一个20*20的棋盘,我下了两步,朋友下了一步。
首先,要创建一个二维数组,来保存棋盘数据。
这里使用了一个增强for循环来输出二维数组。
int chessArr1[][] = new int[20][20];
chessArr1[7][7]=1;
chessArr1[8][8]=2;
chessArr1[7][8]=1;
System.out.println("原始的二维数组:");
for (int[] row:chessArr1){
for (int data:row){
System.out.printf("%d\t",data);
}
System.out.println();
}
但是用二维数组来记录数据又好像太占用空间。
所以我和朋友想到了,把二维数组转换为稀疏数组,二维数组存储棋盘需要保存20行20列的所有数据,而稀疏数组保存棋盘只需要保存已经存在的棋子和原始棋盘的行列值,比如我们只下了三个棋子,稀疏数组只用保存四行三列的数据。
所以要创建一个稀疏数组,不过在创建稀疏数组之前,要先遍历出原二维数组中不为0的值得个数,也就是棋子的个数,至于原理,原理会在下边讲清楚。
//遍历二维数组,找出不为0的值的个数
int sum=0;
for (int i=0;i<20;i++){
for (int j=0;j<20;j++){
if (chessArr1[i][j]!=0){
sum++;
}
}
}
//创建对应的稀疏数组
int sparseArr[][]=new int[sum+1][4];
sparseArr[0][0]=20;
sparseArr[0][1]=20;
sparseArr[0][2]=sum;
//遍历二维数组,将非0的数值存放到sparseArr中
int count=0;
for (int i=0;i<20;i++){
for (int j=0;j<20;j++){
if (chessArr1[i][j]!=0){
count++;
sparseArr[count][0]=i;
sparseArr[count][1]=j;
sparseArr[count][2]=chessArr1[i][j];
}
}
}
//输出稀疏数组
System.out.println();
System.out.println("得到的稀疏数组为:");
for (int i=0;i<sparseArr.length;i++){
System.out.printf("%d\t%d\t%d\t\n",sparseArr[i][0],sparseArr[i][1],sparseArr[i][2]);
}
System.out.println();
输出的稀疏数组如下:
20 20 3
7 7 1
7 8 1
8 8 2
稀疏数组的第一行,依次为原始二维数组的行、列、不为0的值的个数。
第二行数值依次为我的第一个棋子的行、列、值。
第三行第四行原理同第二行。
如此看来,稀疏数组确实比二维数组占用空间小。
这样我和小伙伴用稀疏数组保存后就可以出门办事去了,不用担心熊孩子捣乱的问题了。
当我和小伙伴办完事回来后,需要继续下刚才未完成的五子棋,就需要将稀疏数组再转换为二维数组,就可以了。
首先创建新的二维数组。
先读取稀疏数组的第一行数据,先把棋盘大小恢复出来。
再读取后几行数据,把值赋给新的二维数组。
//将稀疏数组回复为二维数组
//先读取稀疏数组第一行,创建原始二维数组
int chessArr2[][]=new int[sparseArr[0][0]][sparseArr[0][1]];
//再读取稀疏数组的后几行
for (int i=1;i<sparseArr.length;i++){
chessArr2[sparseArr[i][0]][sparseArr[i][1]]=sparseArr[i][2];
}
//输出恢复后的二维数组
System.out.println();
System.out.println("恢复后的二维数组:");
for (int[]row: chessArr2){
for (int data: row){
System.out.printf("%d\t",data);
}
System.out.println();
}
到这里,我和小伙伴就可以继续下未完成的五子棋了。