稀疏數組 SparseArray
1. 案例分析
- 稀疏數組和二維數組,使兩種數據結構可以輕鬆的轉換,
從而實現五子棋程序中有存盤和續上盤的功能。
- 規約:棋盤沒有放棋子爲0,白子爲1,黑子爲2
- 當一個二維數組中大部分元素爲0,或者爲同一個值的數組時,可以使用稀疏數組來保存該數組。
- 下面是稀疏數組儲存數據的結構:
- 記錄數組 一共有幾行幾列,有多少個不同的值
- 把具有不同值的元素的行列及值記錄在一個小規模的數組中-
2. 代碼實現
接下來我們通過Java代碼來完成二維數組與稀疏數組之間的轉換。
我們首先需要知道:
在二維數組中數組名.length指示數組的行數,數組名[行下標] .length指示該行中的元素個數。
我們把二維數組轉換成稀疏數組,並且儲存到
map.data
中,再通過Java中Io流讀取文件進行復原。
2.1 二維數組轉存爲稀疏數組
- 首先我們創建一個11*11的二維數組(五子棋棋盤)
- 在二維數組裏面,0 1 2 分別表示 沒有放棋子 黑子 白子
- 遍歷二維數組,顯示原始的棋盤佈局
- 我們首先通過遍歷二維數組,獲得棋子的個數sum
- 根據已知的棋子數,創建稀疏數組
int[][] sparseArr = new int[sum+1][3];
- 進行賦值:根據上圖結合着稀疏數組的結構品味~~
- 遍歷二維數組,將非零值放到sparseArr中,下面是二維數組轉稀疏數組的核心邏輯~~
- 輸出稀疏數組的形式,並且存盤(即通過IO流把稀疏數組保存到硬盤中)
public class SparseArrayOut{
//創建一個main方法,用來實現五子棋(二維數組轉存爲稀疏數組)
public static void main(String[] args) throws IOException{
//第一步:創建一個11*11的二維數組(五子棋棋盤)
int[][] array = new int[11][11];
//在二維數組裏面,0 1 2 分別表示 沒有放棋子 黑子 白子
array[2][1] = 1;
array[2][3] = 2;
array[4][5] = 2;
//遍歷二維數組,顯示原始的棋盤佈局
System.out.println("原始的二維數組");
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
System.out.print(array[i][j]);
}
System.out.println();
}
//將二維數組轉成稀疏數組,首先遍歷數組獲得值不爲0的個數
int sum = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if(array[i][j]!=0) {
//sum就是value[0]的值
sum++;
}
}
}
//得到棋子的數量
System.out.println("這局共有"+sum+"個棋子");
//根據已知的棋子數,創建稀疏數組
int[][] sparseArr = new int[sum+1][3];
//給稀疏數組賦值
sparseArr[0][0] = 11;
sparseArr[0][1] = 11;
sparseArr[0][2] = sum;
//遍歷二維數組,將非零值放到sparseArr中
int count = 0;//用於記錄是第幾個非0數據,即是索引
for (int i = 0; i <array.length; i++) {
for (int j = 0; j < array.length; j++) {
if(array[i][j]!=0) {
//這一段是?
count++;
sparseArr[count][0]=i;
sparseArr[count][1]=j;
sparseArr[count][2]=array[i][j];
}
}
}
//輸出稀疏數組的形式,並且存盤
System.out.println("得到稀疏數組爲......");
File file = new File("E:/file/","map.data");
FileOutputStream fos = new FileOutputStream(file);
for (int i = 0; i < sparseArr.length; i++) {
// %d 打印十進制整數
// \t 橫向製表符
// \n 換行
System.out.printf("%d\t%d\t%d\t\n",sparseArr[i][0],sparseArr[i][1],sparseArr[i][2]);
fos.write(sparseArr[i][0]);
fos.write(sparseArr[i][1]);
fos.write(sparseArr[i][2]);
}
fos.close();
System.out.println();
}
}
2.2 從map.data
中讀取數據,並將其還原成二維數組
- 先讀取稀疏數組的第一行,根據第一行新建數組
- 讀取稀疏數組後幾行數據
- 最後輸出恢復後的數據
public class SparseArrayIn{
//創建一個main方法,用來實現五子棋
public static void main(String[] args) throws IOException{
File file = new File("E:/file/","map.data");
FileInputStream fis = new FileInputStream(file);
int row = fis.read();
int col = fis.read();
int value = fis.read();
//1.先讀取稀疏數組的第一行,根據第一行新建數組
int[][] array2 = new int[row][col];
//2.讀取稀疏數組後幾行數據
for (int i = 1; i <= value; i++) {
int rows = fis.read();
int cols = fis.read();
int values = fis.read();
array2[rows][cols]=values;
}
fis.close();
//輸出恢復後的數據
System.out.println("恢復後的二維數組");
for (int[] rowss : array2) {
for (int data : rowss) {
System.out.printf("%d\t",data);
}
System.out.println();
}
}
}