开始之前我们先来考虑一个问题.
在一个五子棋程序中,有存盘退出和续上盘的功能。如下
我们要保存一个棋盘,用一个二维数组来保存如右图.
分析问题:
因为该二维数组的很多值是默认值0, 因此记录了很多没有意义的数据,这样子就浪费很多空间.假如我们只记录不是0的元素就能节省很多空间.所以就引出稀疏数组.我们可以用稀疏数组来存储上面的二维数组(棋盘).
基本介绍
当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方法是:
- 记录数组一共有几行几列,有多少个不同的值
- 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模
举例说明:
如图的数组我们可以存储在如下的结构中:
说明:
- 使用稀疏数组,来保留类似前面的二维数组(棋盘、地图等等)
- 把稀疏数组存盘,并且可以从新恢复原来的二维数组数
整体思路分析
代码实现:
package mystruct;
public class SparseArrayException extends Exception{
SparseArrayException(){
}
SparseArrayException(String name){
super(name);
}
}
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
package mystruct;
import java.util.Arrays;
public class SparseArray {
//存放数组的总行数
private int row;
//存放数组的总列数
private int col;
//存放数组中不为0的个数
private int count;
//存放数组中不为0的元素的信息
private int data[][];
/**
* 稀疏矩阵的构造方法
* @param array
* @throws SparseArrayException
*/
SparseArray(final int array[][]) throws SparseArrayException {
checkArray(array);
row = array.length;//设置行数
col = array[0].length;//设置列数
setCount(array);//设置数组中不为0的个数
parseData(array);
}
/**
* 保存数组中不为0的个数
* @param array
*/
private void parseData(final int array[][]){
//用来记录data存放的位置,记得和this.count做区别
int count = 0;
//通过不为0的个数创建数组用来存放不为0的行数,列数和值.
data = new int[this.count][3];
//遍历array,找出不为0的元素
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
if (array[i][j] != 0){
data[count][0] = i;
data[count][1] = j;
data[count][2] = array[i][j];
count++;
}
}
}
}
/**
* 检查array数组是否为空
* @param array
* @throws SparseArrayException
*/
private void checkArray(final int array[][]) throws SparseArrayException {
if(array == null || array[0] == null){
throw new SparseArrayException("数组为null");
}
}
/**
* 统计数组中不为0的个数来设置count的值
* @param array
* @throws SparseArrayException
*/
private void setCount(final int array[][]) throws SparseArrayException {
count = 0;
checkArray(array);
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
if (array[i][j] != 0){
count++;//计算数组中不为0的个数
}
}
}
}
/**
* 把稀疏矩阵转成数组
* @return
*/
public int[][] parseToArray(){
int [][]array = new int[row][col];
for (int i = 0; i < count; i++) {
array[data[i][0]][data[i][1]] = data[i][2];
}
return array;
}
public String dataToString(){
String temp = "";
for (int i = 0; i < count; i++) {
temp += data[i][0] + " " + data[i][1] + " " + data[i][2] + "\n";
}
return temp;
}
@Override
public String toString() {
return "SparseArray{" +
"row=" + row +
", col=" + col +
", count=" + count +
", data=[ \n" + dataToString() +
"]}";
}
/**
* 测试矩阵
* @param args
*/
public static void main(String[] args) throws SparseArrayException {
//定义一个数组
int chessArr[][] = new int[11][11];
chessArr[1][2] = 1;
chessArr[2][3] = 2;
chessArr[3][4] = 3;
//输出显示一下
System.out.println("===============原数组================");
for (int i = 0; i < chessArr.length; i++) {
for (int j = 0; j < chessArr[i].length; j++) {
System.out.print(chessArr[i][j] + " ");
}
System.out.println();
}
System.out.println("====================================");
SparseArray sparseArray = new SparseArray(chessArr);
System.out.println("===============输出矩阵=====================");
System.out.println(sparseArray);
System.out.println("==========================================");
int[][] arr = sparseArray.parseToArray();
System.out.println("===============转换数组================");
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
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 0 0 0 0 0 0 0
0 0 0 0 3 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
====================================
===============输出矩阵=====================
SparseArray{row=11, col=11, count=3, data=[
1 2 1
2 3 2
3 4 3
]}
==========================================
===============转换数组================
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 0 0 0 0 0 0 0
0 0 0 0 3 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
====================================