1.稀疏数组
1.1稀疏数组的应用场景
数组存储实例:
如图是一个9×9的棋盘
使用数组存储此个棋盘也很简单,假如白旗是1,黑旗是2可以存储为:
例:数组1.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 1 0 0 0 0 0
0 0 0 0 2 0 0 0 0
0 0 0 1 0 2 0 0 0
0 0 0 0 2 0 0 0 0
0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0
使用二维数组可以非常轻松的将数据保存,但是反观也会有大量的无用数据被记录着。
因此稀疏数组可以完美解决此问题。
**稀疏数组的处理方法: **
- 记录数组有几行几列,有多少个不同的值
- 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
以上面数组1.1为例稀疏数组存取为:
行(row) | 列(col) | 值(value) | |
---|---|---|---|
[0] | 9 | 9 | 6 |
[1] | 3 | 3 | 1 |
[2] | 4 | 4 | 2 |
[3] | 5 | 3 | 1 |
[4] | 5 | 5 | 2 |
[5] | 6 | 4 | 2 |
[6] | 7 | 3 | 1 |
因此将一个9×9的二维数组存储调整为3×7的二维数组
总结:面对有着大量的无用数据的数组时,可以使用稀疏数组代替,会提升不少的效率和节省空间。
1.2稀疏数组的转换思路
**二维数组转换稀疏数组 **
- 根据二维数组的行(row)、列(col)和遍历获取到的有效值(value)存放在稀疏数组的下标0
- 稀疏数组的的大小根据有效值个数sum而定,为sparseArr [sum+1] [3]
- 根据二维数组有效值所在的行、列、和值存储到稀疏数组中
**稀疏数组转换为二维数组 **
- 先读取稀疏数组第一行的行数和列数,创建原始的二维数组
- 在根据稀疏数组后面的,有效值,和有效值所在的行数和列数还原成原始的二维数组
1.3代码实现稀疏算法棋盘的存取及复盘
要求:将这个9x9的棋盘存储成稀疏数组并且,并且从稀疏舒服还原成二维数组。
*扩展:将稀疏数组存储到文件map.data中,并取出来还原为棋盘。
代码实现:
package com.fengyu.sparseArray;
import java.io.*;
public class SparseArray {
public static void main(String[] args) throws IOException {
//先创建一个9×9的棋盘
int chessArray[][] = new int[9][9];
//0表示没有棋子,1表示白棋,2表示黑旗
chessArray[3][3] = 1;
chessArray[4][4] = 2;
chessArray[5][3] = 1;
chessArray[5][5] = 2;
chessArray[6][4] = 2;
chessArray[7][3] = 1;
//输出二维数组
System.out.println("原始二维数组为:");
for (int[] row:chessArray){
for (int item:row){
System.out.printf("%d\t",item);
}
System.out.println();
}
System.out.println("-------------------------------------------------------------------------------");
//将二维数组转换为稀疏数组
//首先遍历获得数组chessArray的有效元素
int sum = 0;
for (int[] row:chessArray){
for (int item:row){
if (item!=0){
sum++;
}
}
}
//得到有效元素值创建稀疏数组
int sparseArray[][] = new int[sum+1][3];
//给数组的第一行赋值行数、列数、有效元素个数
sparseArray[0][0] = chessArray.length;
sparseArray[0][1] = chessArray[0].length;
sparseArray[0][2] = sum;
//将初始二维数组赋值给稀疏数组
int count = 0;
for (int i=0;i<chessArray.length;i++){
for (int j=0;j<chessArray[i].length;j++){
if (chessArray[i][j]!=0) {
count++;
sparseArray[count][0] = i;
sparseArray[count][1] = j;
sparseArray[count][2] = chessArray[i][j];
}
}
}
//输出稀疏数组
System.out.printf("改变为稀疏数组为:\n下标\t行\t列\t值\n");
count = 0;
for (int[] row:sparseArray){
System.out.printf("%d\t%d\t%d\t%d\n",count,row[0],row[1],row[2]);
count++;
}
}
System.out.println("-------------------------------------------------------------------------------");
//将稀疏数组显示回初始二维数组
//根据稀疏数组第一行创建二维数组
int chessArray2[][] = new int[sparseArray[0][0]][sparseArray[0][1]];
//回显数据
//计数器,初始值为1
count = 1;
while (count<=sparseArray[0][2]){
//将对应的下标赋值
chessArray2[sparseArray[count][0]][sparseArray[count][1]] = sparseArray[count][2];
count++;
}
//输出二维数组
System.out.println("回显原始二维数组为:");
for (int[] row:chessArray2){
for (int item:row){
System.out.printf("%d\t",item);
}
System.out.println();
}
}
}
扩展部分实现:
1.将稀疏数组写入文件
//保存稀疏数组
File file = new File("D:\\数据结构测试区\\DataStructures\\src\\map.data");
FileOutputStream fos = new FileOutputStream(file);
OutputStreamWriter write = new OutputStreamWriter(fos, "UTF-8");
//输出稀疏数组
System.out.printf("改变为稀疏数组为:\n下标\t行\t列\t值\n");
count = 0;
for (int[] row:sparseArray){
System.out.printf("%d\t%d\t%d\t%d\n",count,row[0],row[1],row[2]);
count++;
//写入文件
if (count > sum){
write.append(row[0]+","+row[1]+","+row[2]);
}else {
write.append(row[0]+","+row[1]+","+row[2]+",");
}
}
System.out.println("写入文件中...");
write.close();
fos.close();
2.从文件读取出来并转换成稀疏数组
package com.fengyu.sparseArray;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class ReadSparseArray {
public static void main(String[] args) throws IOException {
//首先创建读取文件
File file = new File("D:\\数据结构测试区\\DataStructures\\src\\map.data");
System.out.println("读取文件.....");
//实例化文件字节输入流
FileInputStream fileInputStream = new FileInputStream(file);
//实例化字符转换流
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
//创建StringBuffer存储字符
StringBuffer sb = new StringBuffer();
while (inputStreamReader.ready()){
//转换成char添加到字符串中
sb.append((char) inputStreamReader.read());
}
System.out.println(sb.toString());
//关闭流
inputStreamReader.close();
fileInputStream.close();
//还原为稀疏数组
String[] str = sb.toString().split(",");
//创建稀疏数组
int sparseArray[][] = new int[str.length/3][3];
//给稀疏数组赋值
int count=0;
for (String s:str){
sparseArray[count/3][count%3] = Integer.parseInt(s);
count++;
}
//输出稀疏数组
System.out.printf("改变为稀疏数组为:\n下标\t行\t列\t值\n");
count = 0;
for (int[] row:sparseArray){
System.out.printf("%d\t%d\t%d\t%d\n",count,row[0],row[1],row[2]);
count++;
}
}
}