一个实际的需求
编写的五子棋程序中,有存盘退出和续上盘的功能。
分析问题:
因为该二维数组的很多值是默认值0,因此记录了很多没有意义的数据.->稀疏数组。
基本介绍
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法是:
- 记录数组一共有几行几列,有多少个不同的值
- 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
稀疏数组举例说明
应用实例
- 使用稀疏数组,来保留类似前面的二维数组(棋盘、地图等等)
- 把稀疏数组存盘,并且可以从新恢复原来的二维数组数
- 整体思路分析
- 代码实现
package com.sukang.sparsearray;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* @description: 普通二维数组转稀疏数组,稀疏数组转普通二维数组
* @author: sukang
* @date: 2019-12-25 15:20
*/
public class SparseArray {
public static void main(String[] args) {
System.out.println("===============普通二维数组转稀疏数组,并写入到文件中====================");
/**
* 将棋盘当做一个普通的二维数组,数组里面的值为0表示无棋子,为1表示为黑子,为2表示为白子
*/
System.out.println("1、首先去声明一个二维数组作为棋盘,并且给其默认的赋几个值");
int[][] chessArr = new int[11][11];
chessArr[1][2] = 1;
chessArr[4][5] = 2;
chessArr[6][9] = 1;
System.out.println("打印普通的二维数组");
for (int[] row :chessArr) {
for (int data :row) {
System.out.printf("%d\t", data);
}
System.out.println();
}
System.out.println("2、将普通的二维数组转为稀疏数组");
//首先计算出普通二维数组中有多少个有效的数据
int num = 0;
for (int[] row :chessArr) {
for (int data :row) {
if(data != 0){
num++;
}
}
}
//声明稀疏数组并且给第一行赋值
int[][] sprseArr = new int[num + 1][3];
sprseArr[0][0] = 11;
sprseArr[0][1] = 11;
sprseArr[0][2] = num;
//将普通的二维数组赋值给稀疏数组
//定义一个count,当二维数组的值不为0时给其加1
int count = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if(chessArr[i][j] != 0){
count ++;
sprseArr[count][0] = i;
sprseArr[count][1] = j;
sprseArr[count][2] = chessArr[i][j];
}
}
}
//遍历稀疏数组
for (int i = 0; i < sprseArr.length; i++) {
System.out.printf("%d\t%d\t%d\t", sprseArr[i][0], sprseArr[i][1], sprseArr[i][2]);
System.out.println();
}
System.out.println("3、将稀疏数组写入到文件中");
String fileName = "D:\\MyProject\\DataStructures\\src\\resource\\map.data";
writeSpareToFile(sprseArr, fileName);
System.out.println("===============从文件中读出稀疏数组,然后转为普通二维数组====================");
System.out.println("1、从文件中读出稀疏数组");
int[][] sparseArr1 = readFileToSpare(fileName);
//遍历稀疏数组
for (int i = 0; i < sparseArr1.length; i++) {
System.out.printf("%d\t%d\t%d\t", sparseArr1[i][0], sparseArr1[i][1], sparseArr1[i][2]);
System.out.println();
}
System.out.println("2、将稀疏数组转为普通数组");
//根据稀疏数组的第一行数据去声明普通数组
int[][] chessArr1 = new int[sparseArr1[0][0]][sparseArr1[0][1]];
//将稀疏数组赋值给普通数组
for (int i = 1; i < sparseArr1.length; i++) {
chessArr1[sparseArr1[i][0]][sparseArr1[i][1]] = sparseArr1[i][2];
}
//遍历普通的二维数组
for (int[] row :chessArr1) {
for (int data :row) {
System.out.printf("%d\t", data);
}
System.out.println();
}
}
/**
* @description: 将稀疏数据写入文件中
* @param sparseArray
* @param fileName
* @return: void
* @author: sukang
* @date: 2019/12/25 17:10
*/
public static void writeSpareToFile(int[][] sparseArray, String fileName){
File file = new File(fileName);
FileWriter fw = null;
BufferedWriter bw = null;
try {
fw = new FileWriter(file);
bw = new BufferedWriter(fw);
for (int i = 0; i < sparseArray.length; i++) {
StringBuffer sb = new StringBuffer();
for (int j = 0; j < sparseArray[i].length; j++) {
sb.append(sparseArray[i][j] + " ");
}
sb.append("\r\n");
bw.write(sb.toString());
bw.flush();
}
} catch ( IOException e ) {
e.printStackTrace();
} finally {
try {
if(bw != null){
bw.close();
}
if(fw != null){
fw.close();
}
} catch ( IOException e ) {
e.printStackTrace();
}
}
}
/**
* @description: 从文件中读取稀疏数组
* @param fileName
* @return: int[][]
* @author: sukang
* @date: 2019/12/26 14:29
*/
public static int[][] readFileToSpare(String fileName){
int[][] spare = {};
File file = new File(fileName);
FileReader fr = null;
BufferedReader br = null;
try {
List<String> strs = new ArrayList<>();
fr = new FileReader(file);
br = new BufferedReader(fr);
String line = null;
while ((line = br.readLine()) != null){
strs.add(line);
}
spare = new int[strs.size()][strs.get(0).split(" ").length];
for (int i = 0; i < strs.size(); i++) {
String[] str = strs.get(i).split(" ");
for (int j = 0; j < str.length; j++) {
spare[i][j] = Integer.parseInt(str[j]);
}
}
} catch ( FileNotFoundException e ) {
e.printStackTrace();
} catch ( IOException e ) {
e.printStackTrace();
}finally {
try {
if(br != null){
br.close();
}
if(fr != null){
fr.close();
}
} catch ( IOException e ) {
e.printStackTrace();
}
return spare;
}
}
}