问题背景:
如何存储一盘五子棋的状态。
一般的想法是:创建一个二维数组,没有棋子的交叉点的值为0,黑棋所下的地方为1,白棋所下的地方为2.
但是如果我们这个棋盘很大,比如说20*20个点,而游戏过程中我们只需要占用很少的空间就能完成这盘棋,或者说游戏过程中需要存档,悔棋,我们就需要进行很多次的存储操作,可是我们总不能每次都往硬盘里存一个容量很大,但有用信息很少的二维数组吧,所以这就引出了稀疏数组。
而把二维数组转成稀疏数组也很简单,请看下面这张图(此图来源于:https://www.cnblogs.com/ekig/p/14747418.html)
代码实现
先将代码拆开来看。
首先是创建二维数组
//1. 创建二维数组
int[][] chessArray1 = new int[11][11];
chessArray1[1][2] = 1;
chessArray1[2][3] = 2;
System.out.println("原始的二维数组为:");
for(int[] row : chessArray1){
for(int data : row){
System.out.printf("%d\t",data);
}
System.out.println();
}
然后将二维数组转换成稀疏数组:
//2. 将二维数组转成稀疏数组
int sum=0;
for (int i = 0; i < chessArray1.length; i++) {
for (int j = 0; j < chessArray1[0].length; j++) {
if(chessArray1[i][j]!=0){
sum++;
}
}
}
int[][] sparseArray = new int[sum+1][3];
sparseArray[0][0] = chessArray1.length;
sparseArray[0][1] = chessArray1[0].length;
sparseArray[0][2] = sum;
int count = 0;
for (int i = 0; i < chessArray1.length; i++) {
for (int j = 0; j < chessArray1[0].length; j++) {
if(chessArray1[i][j]!=0){
count++;
sparseArray[count][0] = i;
sparseArray[count][1] = j;
sparseArray[count][2] = chessArray1[i][j];
}
}
}
//打印稀疏数组
System.out.println("转换后的稀疏数组为:");
for(int[] row : sparseArray){
for(int data : row){
System.out.printf("%d\t",data);
}
System.out.println();
}
如果涉及到存档操作,还需要将稀疏数组存入磁盘中
//3. 将稀疏数组存入磁盘中
System.out.println("将稀疏数组存入磁盘中----------");
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter("D:\\sparsearray.txt");
for(int[] row : sparseArray){
fileWriter.write(row[0]+"\t"+row[1]+"\t"+row[2]+"\t");
//fileWriter.write("\r\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("写入完毕!");
既然有存储操作,也就会有读取操作
//4. 从磁盘中读取稀疏数组
System.out.println("从磁盘中读取稀疏数组----------");
int b=0;
FileReader fileReader = null;
try {
fileReader = new FileReader("D:\\sparsearray.txt");
StringBuffer sb = new StringBuffer();
while ((b = fileReader.read())!=-1){
//将读到的字符存入缓冲区中
sb.append((char)b);
}
//s中存放的是字符串形式的稀疏数组
//System.out.println(sb);
String s = sb.toString();
String[] ss = sb.toString().split("\t");
//System.out.println(ss[3]);
//System.out.println(ss[4]);
//恢复成正常的稀疏数组
int sum2=0;
int[][] sparseArray2 = new int[ss.length/3][3];
for(int i=0;i<ss.length;i+=3){
sparseArray2[sum2][0] = Integer.parseInt(ss[i]);
sparseArray2[sum2][1] = Integer.parseInt(ss[i+1]);
sparseArray2[sum2][2] = Integer.parseInt(ss[i+2]);
sum2++;
}
System.out.println("还原的稀疏数组如下:");
for(int[] row : sparseArray2){
for(int data : row){
System.out.printf("%d\t",data);
}
System.out.println();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
最后把稀疏数组还原成二维数组:
//5. 稀疏数组转二维数组
int[][] chessArray2 = new int[sparseArray[0][0]][sparseArray[0][1]];
for(int i = 1;i<=sum;i++){
chessArray2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
}
System.out.println("恢复后的二维数组为:");
for(int[] row : chessArray2){
for(int data : row){
System.out.printf("%d\t",data);
}
System.out.println();
}
完整代码如下:
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class SparseArray {
public static void main(String[] args) {
//1. 创建二维数组
int[][] chessArray1 = new int[11][11];
chessArray1[1][2] = 1;
chessArray1[2][3] = 2;
System.out.println("原始的二维数组为:");
for(int[] row : chessArray1){
for(int data : row){
System.out.printf("%d\t",data);
}
System.out.println();
}
//2. 二维数组转成稀疏数组
int sum=0;
for (int i = 0; i < chessArray1.length; i++) {
for (int j = 0; j < chessArray1[0].length; j++) {
if(chessArray1[i][j]!=0){
sum++;
}
}
}
int[][] sparseArray = new int[sum+1][3];
sparseArray[0][0] = chessArray1.length;
sparseArray[0][1] = chessArray1[0].length;
sparseArray[0][2] = sum;
int count = 0;
for (int i = 0; i < chessArray1.length; i++) {
for (int j = 0; j < chessArray1[0].length; j++) {
if(chessArray1[i][j]!=0){
count++;
sparseArray[count][0] = i;
sparseArray[count][1] = j;
sparseArray[count][2] = chessArray1[i][j];
}
}
}
//打印稀疏数组
System.out.println("转换后的稀疏数组为:");
for(int[] row : sparseArray){
for(int data : row){
System.out.printf("%d\t",data);
}
System.out.println();
}
//3. 将稀疏数组存入磁盘中
System.out.println("将稀疏数组存入磁盘中----------");
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter("D:\\sparsearray.txt");
for(int[] row : sparseArray){
fileWriter.write(row[0]+"\t"+row[1]+"\t"+row[2]+"\t");
//fileWriter.write("\r\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("写入完毕!");
//4. 从磁盘中读取稀疏数组
System.out.println("从磁盘中读取稀疏数组----------");
int b=0;
FileReader fileReader = null;
try {
fileReader = new FileReader("D:\\sparsearray.txt");
StringBuffer sb = new StringBuffer();
while ((b = fileReader.read())!=-1){
//将读到的字符存入缓冲区中
sb.append((char)b);
}
//s中存放的是字符串形式的稀疏数组
//System.out.println(sb);
String s = sb.toString();
String[] ss = sb.toString().split("\t");
//System.out.println(ss[3]);
//恢复成正常的稀疏数组
int sum2=0;
int[][] sparseArray2 = new int[ss.length/3][3];
for(int i=0;i<ss.length;i+=3){
sparseArray2[sum2][0] = Integer.parseInt(ss[i]);
sparseArray2[sum2][1] = Integer.parseInt(ss[i+1]);
sparseArray2[sum2][2] = Integer.parseInt(ss[i+2]);
sum2++;
}
System.out.println("还原的稀疏数组如下:");
for(int[] row : sparseArray2){
for(int data : row){
System.out.printf("%d\t",data);
}
System.out.println();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//5. 稀疏数组转二维数组
int[][] chessArray2 = new int[sparseArray[0][0]][sparseArray[0][1]];
for(int i = 1;i<=sum;i++){
chessArray2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
}
System.out.println("恢复后的二维数组为:");
for(int[] row : chessArray2){
for(int data : row){
System.out.printf("%d\t",data);
}
System.out.println();
}
}
}