稀疏数组
关于作者
- 作者介绍
文章目录
在编写的五子棋程序中,有存盘退出和续上盘的功能。
我们发现每次程序启动之后它的棋子还可以是之前的位置,这是怎么实现的,今天我们来探究一下原理。
分析问题:
该二维数组的很多值是默认值 0, 因此记录了很多没有意义的数据(这里我们称为无效数据)->稀疏数组。
基本介绍
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法是:
- 记录数组一共有几行几列,有多少个不同的值
- 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
应用实例
- 保留类似前面的二维数组(棋盘、地图等等)
- 把稀疏数组存盘,并且可以从新恢复原来的二维数组数
图解
二维数组 转 稀疏数组的思路:
-
遍历 原始的二维数组,得到有效数据的个数 sum
-
根据sum 就可以创建 稀疏数组 sparseArr int[sum + 1] [3]
-
将二维数组的有效数据数据存入到 稀疏数组
稀疏数组 转 原始的二维数组的思路:
-
先读取稀疏数组的第一行,根据第一行的数据,创建原始的二维数组,比如上面的 chessArr2 = int [11] [11]
-
在读取稀疏数组后几行的数据,并赋给 原始的二维数组 即可.
代码实现
package day1;
public class SparseArray {
public static void main(String[] args) {
// TODO Auto-generated method stub
//新建一个二位数组11*11
int [][] chess = new int [11][11];
chess[1][2] = 1;
chess[2][3] = 2;
System.out.println("原始数组——————————————————");
for(int[] row:chess){
for(int data:row){
System.out.printf("%d\t",data);
}
System.out.println();
}
int sum=0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if(chess[i][j]!=0)sum++;
}
}
System.out.println();
System.out.println();
System.out.println("sum="+sum);
System.out.println("稀疏数组——————————————————");
System.out.println("row\tcol\tvalue");
//创建稀疏数组
int [][] sparseArray = new int [sum+1][3];
sparseArray[0][0] = 11;
sparseArray[0][1] = 11;
sparseArray[0][2] = sum;
int count=0;//count 用于记录是第几个非 0 数据
// 遍历二维数组,将非 0 的值存放到 sparseArr 中
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if(chess[i][j]!=0) {
count++;
sparseArray[count][0] = i;
sparseArray[count][1] = j;
sparseArray[count][2] = chess[i][j];
}
}
}
//输出稀疏数组
for (int i = 0; i < sparseArray.length; i++) {
System.out.println(sparseArray[i][0]+"\t"+sparseArray[i][1]+"\t"+sparseArray[i][2]);
}
//稀疏数组恢复为原数组
int [][]chess2 = new int [sparseArray[0][0]][sparseArray[0][1]];
//注意恢复时i是从1开始而不是从0开始
//判断循环的次数也是之前稀疏数组的长度
for (int i = 1; i < sparseArray.length; i++) {
chess2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
}
System.out.println();
System.out.println();
System.out.println("恢复的二维数组——————————————————");
for(int[] row:chess){
for(int data:row){
System.out.printf("%d\t",data);
}
System.out.println();
}
}
}
课后练习
-
在前面的基础上,将稀疏数组保存到磁盘上,比如 map.data
-
恢复原来的数组时,读取 map.data 进行恢复
存档:
package com.cz.Sparsearray;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
* @ProjectName: Data_structure
* @Package: com.cz.Sparsearray
* @ClassName: SparseArrayWrite
* @Author: 张晟睿
* @Date: 2022/2/21 17:34
* @Version: 1.0
*/
public class SparseArrayWrite {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
//新建一个二位数组11*11
int[][] chess = new int[11][11];
chess[1][2] = 1;
chess[2][3] = 2;
System.out.println("原始数组——————————————————");
for (int[] row : chess) {
for (int data : row) {
System.out.printf("%d\t", data);
}
System.out.println();
}
int sum = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (chess[i][j] != 0) sum++;
}
}
System.out.println();
System.out.println();
System.out.println("sum=" + sum);
//创建稀疏数组
int[][] sparseArray = new int[sum + 1][3];
sparseArray[0][0] = 11;
sparseArray[0][1] = 11;
sparseArray[0][2] = sum;
int count = 0;//count 用于记录是第几个非 0 数据
// 遍历二维数组,将非 0 的值存放到 sparseArr 中
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (chess[i][j] != 0) {
count++;
sparseArray[count][0] = i;
sparseArray[count][1] = j;
sparseArray[count][2] = chess[i][j];
}
}
}
File file = new File("./data/map.data");
if(!file.getParentFile().exists()){//父目录
file.getParentFile().mkdirs();//创建父目录
}
if(file.exists()){//文件存在
file.delete();
}else{//文件不存在
file.createNewFile();//创建文件
}
FileWriter fileWriter = new FileWriter(file);
BufferedWriter bw = new BufferedWriter(fileWriter);
System.out.println("存档中......");
for (int i = 0; i < sparseArray.length; i++) {
String s = "" + sparseArray[i][0] + "\t" + sparseArray[i][1] + "\t" + sparseArray[i][2] + "\t\n";
bw.write(s);
}
//输出稀疏数组
System.out.println("稀疏数组——————————————————");
System.out.println("row\tcol\tvalue");
for (int i = 0; i < sparseArray.length; i++) {
System.out.println(sparseArray[i][0] + "\t" + sparseArray[i][1] + "\t" + sparseArray[i][2]);
}
bw.close();
}
}
读档:
package com.cz.Sparsearray;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* @ProjectName: Data_structure
* @Package: com.cz.Sparsearray
* @ClassName: SparseArrayRead
* @Author: 张晟睿
* @Date: 2022/2/21 17:51
* @Version: 1.0
*/
public class SparseArrayRead {
public static void main(String[] args) throws IOException {
File file = new File("./data/map.data");
if(file.getParentFile().exists()&&file.exists()){//父目录和子目录存在
System.out.println("开始读档......");
}else {
System.out.println("该文件下无文件");
}
FileReader fileReader = new FileReader(file);
BufferedReader br = new BufferedReader(fileReader);
List<String> list = new ArrayList<>();
String s = "";
while ((s = br.readLine()) != null){
list.add(s);
}
//创建稀疏数组
int sparseArrayRead[][] = new int [list.size()][3];
String s1 = list.get(0);
String split[] = s1.split("\t");
//将稀疏数组的二维表构建出来
sparseArrayRead[0][0] = Integer.parseInt(split[0]);
sparseArrayRead[0][1] = Integer.parseInt(split[1]);
sparseArrayRead[0][2] = Integer.parseInt(split[2]);
// 读取文件中的数组将其输出到数组
for (int i = 1; i < list.size(); i++) {
String s2 = list.get(i);
String split1[] = s2.split("\t");
for (int j = 0; j < split1.length; j++) {
sparseArrayRead[i][j] = Integer.parseInt(split1[j]);
}
}
//输出稀疏数组
for (int i = 0; i < sparseArrayRead.length; i++) {
System.out.println(sparseArrayRead[i][0] + "\t" + sparseArrayRead[i][1] + "\t" + sparseArrayRead[i][2]);
}
//稀疏数组恢复为原数组
int[][] chess2 = new int[sparseArrayRead[0][0]][sparseArrayRead[0][1]];
//注意恢复时i是从1开始而不是从0开始
//判断循环的次数也是之前稀疏数组的长度
for (int i = 1; i < sparseArrayRead.length; i++) {
chess2[sparseArrayRead[i][0]][sparseArrayRead[i][1]] = sparseArrayRead[i][2];
}
System.out.println();
System.out.println("恢复的二维数组——————————————————");
for (int[] row : chess2) {
for (int data : row) {
System.out.printf("%d\t", data);
}
System.out.println();
}
}
}