一、稀疏数组
1、定义
稀疏数组可以看做是普通数组的压缩,但是这里说的普通数组是值无效数据量远大于有效数据量的数组
2、概念
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组
3、处理方法
1)稀疏数组的处理方式是:记录数组一共有几行几列,有多少个不同值;
2)把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模;
案例:以棋盘为例
我们可以将棋盘看成一个二维数组
- 用0表示没有被下过的地方.
- 用1表示黑子.
- 用2表示蓝子.
代码演示
//创建一个原始的二维数组 11 * 11
//棋盘 -> 0 表示没有棋子, 1 表示黑子 2表示蓝子
int row = 11;//行
int col = 11; //列
int chessArr1[][] = new int[row][col];
//给棋盘赋值
chessArr1[1][2] = 1;
chessArr1[2][3] = 2;
chessArr1[2][4] = 1;
//输出原始的二维数组
for (int[] r : chessArr1) {
for (int data : r) {
System.out.printf("%d\t", data);
}
System.out.println();
}
输出的结果:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
将原始数组转换成 稀疏数组:
稀疏数组的格式是固定的 一般为3列 1列为 原数组的行 2列为原数组的列 3为原数组的有效值总数
//将二维数组 转 稀疏数组的思路
//1. 先遍历原始数组 计算处原始数组中的有效值数量
int sum = 0;
for (int i = 0; i < chessArr1.length; i++) {
for (int j = 0; j < chessArr1[i].length; j++) {
if (chessArr1[i][j] != 0) {
sum++;
}
}
}
//2.创建对应的稀疏数组
int[][] sparaseArray = new int[sum + 1][3];
//给稀疏数组的第一行赋值
sparaseArray[0][0] = 11; //行
sparaseArray[0][1] = 11; //列
sparaseArray[0][2] = sum; //数量
//给剩下的稀疏数组赋值
int count = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (chessArr1[i][j] != 0) {
count++;
sparaseArray[count][0] = i;
sparaseArray[count][1] = j;
sparaseArray[count][2] = chessArr1[i][j];
}
}
}
//输出稀疏数组的形式
System.out.println("");
System.out.println("得到稀疏数组为~~~~~");
for (int i = 0; i < sparaseArray.length; i++) {
System.out.printf("%d\t%d\t%d\t\n", sparaseArray[i][0], sparaseArray[i][1], sparaseArray[i][2]);
}
输出结果
得到稀疏数组为~~~~~
11 11 3
1 2 1
2 3 2
2 4 1
将稀疏数组转变为原始数组方法:
//将稀疏数组 转变为 原始数组
//初始化原始数组
// 稀疏数组第一行的 第一个元素为原始数组的行
// 第二个元素为原始数组的列
int chessArr2[][] = new int[sparaseArray[0][0]][sparaseArray[0][1]];
for (int i = 1; i < sparaseArray.length; i++) {
//从第一行开始 将稀疏数组的剩下的有效值 赋值给原数组
chessArr2[sparaseArray[i][0]][sparaseArray[i][1]] = sparaseArray[i][2];
}
System.out.println("原始数组为~~");
for (int[] str : chessArr2) {
for (int data : str) {
System.out.printf("%d\t", data);
}
System.out.println();
}
输出结果为
原始数组为~~
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
二、将稀疏数组存入磁盘
/**
* 将数组写入文件
* @param sparaseArray 数组
* @param path 文件路径
*/
public static void write(int[][] sparaseArray, String path) {
//创建文件
File file = new File(path);
FileWriter write = null;
try {
write = new FileWriter(file);
//写入数据
for (int i = 0; i < sparaseArray.length; i++) {
write.write(sparaseArray[i][0] + " ");
write.write(sparaseArray[i][1] + " ");
write.write(sparaseArray[i][2] + " \n");
}
} catch (
IOException e) {
e.printStackTrace();
}
if (write != null) {
try {
write.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
代码调用
String path = "E:\\map.data";
WritTxt.write(sparaseArray,path);
输出结果
三、从磁盘读取稀疏数组数据
/**
* 从磁盘读取稀疏数组数据
* @param path 文件路径
* @return 返回稀疏数组
*/
public static int[][] readTxt(String path){
File file = new File(path);
//创建稀疏数组
int[][] sparseArray;
//建立 缓冲流
BufferedReader buffReader = null;
try {
buffReader = new BufferedReader(new FileReader(file));
//给稀疏数组初始化
int row = 0;
while(buffReader.readLine()!=null){
row++;
}
sparseArray = new int[row][3];
//将文件的内容读完之后,关闭流,不然读下去会读到空值
buffReader.close();
//重新将流打开
buffReader = new BufferedReader(new FileReader(file));
String str; //因为读取文件是字符串类型 所以用String接收
int i = 0; //稀疏数组行指针
int j = 0; //稀疏数组列指针
while((str = buffReader.readLine()) != null){
String[] sr = str.split( " ");
for (String s : sr ){
sparseArray[i][j] = Integer.parseInt(s);
j++;
}
//下一行重新开始
j = 0;
i++;
}
return sparseArray;
} catch (IOException e) {
e.printStackTrace();
}
if (buffReader!=null){
try {
buffReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
代码调用:
int[][] sparaseArray2 = ReadTxt.readTxt(path);
for (int[] r : sparaseArray2) {
for (int data : r) {
System.out.printf("%d\t", data);
}
System.out.println();
}
输出结果为:
11 11 3
1 2 1
2 3 2
2 4 1