# 稀疏矩陣(Sparse Matrix) 五子棋程序如何存取盤的下棋情況? A:可以使用二維陣列,將黑棋白棋記錄下來。 ![](https://i.imgur.com/PRG8WZ6.png) **思考** Q:該二維陣列很多值默認為0,因此記錄了很多沒意義的數據,該如何去解決? A:可以使用稀疏矩陣來保存該陣列。 ## 稀疏矩陣的處理方法 1. 記錄陣列一共有幾行幾列,有多少個不同的值。 2. 把具有不同值的元素的行列及值記錄在一個小規模的陣列中,從而縮小程式的規模。 以下圖為例,我們可以將原先 6\*7 = 42 的陣列縮減為 9\*3 = 27 的陣列: ![](https://i.imgur.com/7khWDR3.png) **【小結】** 使用稀疏矩陣的情況: - 當一個陣列有很多沒意義數據(0)或相同數據。 處理方法: - 第一行記錄陣列共幾列幾行並且有幾個非0的值。 - 第二行開始用於紀錄每個非0值在陣列第幾列第幾行、值為多少。 ## 二維陣列 轉 稀疏矩陣 **思路** 1. 遍歷原始的二維陣列,得到有效數據的個數(sum)。 2. 根據sum 就可以創建稀疏矩陣`parseMatrix int[sum+1][3]` 3. 將二維陣列的有效數據存入到稀疏矩陣。 ## 稀疏矩陣 轉 二維陣列 **思路** 1. 先讀取稀疏矩陣第一行,根據第一行的數據創建原始的二維陣列,比如上方圖示`chessArr = int[11][11]` 2. 再讀取稀疏矩陣後幾行的數據,並賦給原始的二維陣列。 ## 代碼實現 現在,我們用JAVA來將下方這個二維陣列轉維稀疏矩陣。 ![](https://i.imgur.com/ZgfQYHz.png) ### 創建原始的二維陣列 11*11 0: 沒有旗子, 1:黑子, 2:藍子 ```java= //創建原始的二維陣列 11*11 //0: 沒有旗子, 1:黑子, 2:藍子 int chessArr1[][] = new int[11][11]; chessArr1[1][2] = 1; chessArr1[2][3] = 2; //輸出原始二維陣列 for(int[] row: chessArr1){ for(int data:row){ System.out.printf("%d ",data); } System.out.println(); } ``` ![](https://i.imgur.com/AXhxuyx.png) ### 獲取非0數據個數 先遍歷二維陣列,獲取非0數據個數 ```java= //1.先遍歷二維陣列,獲取非0數據個數 int sum = 0; for(int i=0;i<11;i++){ for(int j=0;j<11;j++){ if(chessArr1[i][j] !=0) sum++; } } System.out.println(sum); ``` ### 創建對應的稀疏矩陣 創建對應的稀疏矩陣並且給稀疏矩陣賦值 ```java= //2.創建對應的稀疏矩陣 int sparseArr[][] = new int[sum+1][3]; //列:sum為非0值的個數+1列存放原始二維陣列資訊 行:列,行,非0值 //給稀疏矩陣賦值 sparseArr[0][0] = 11; sparseArr[0][1] = 11; sparseArr[0][2] = sum; //遍歷二維陣列,將非0值存放到稀疏矩陣中 int count=0; //用於紀錄是第幾個非0數據 for(int i=0;i<11;i++){ for(int j=0;j<11;j++){ if(chessArr1[i][j] !=0){ count++; sparseArr[count][0] = i; sparseArr[count][1] = j; sparseArr[count][2] = chessArr1[i][j]; }; } } //輸出稀疏矩陣 for(int[] row: sparseArr){ for(int data:row){ System.out.printf("%d\t",data); } System.out.println(); } ``` ![](https://i.imgur.com/XrrvgKC.png) ### 恢復原始二維陣列 ```java= //恢復原始二維陣列 int chessArr2[][] = new int[sparseArr[0][0]][sparseArr[0][1]]; //從稀疏矩陣第二行開始讀取數據,並賦給原始二維陣列 for(int i=1;i<sparseArr.length;i++){ chessArr2[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2]; } for(int[] row: chessArr2){ for(int data:row){ System.out.printf("%d ",data); } System.out.println(); } ``` ![](https://i.imgur.com/oAHm7Hv.png) 現在,我們來實作將稀疏矩陣寫入txt檔和從txt檔中讀取出來 ### 寫入稀疏矩陣到txt檔 ```java= import java.io.*; File file = new File("./data.txt"); FileWriter out = new FileWriter(file); //寫入稀疏矩陣內容 for(int i=0;i<sum+1;i++){ for(int j=0;j<3;j++){ out.write(sparseArr[i][j]+"\t"); } out.write("\r\n"); } out.close(); ``` ### 讀取稀疏矩陣到txt檔 ```java= //讀取稀疏矩陣內容 BufferedReader in = new BufferedReader(new FileReader(file)); String line; //一行資料 int row=0; int[][] arr2 = new int[sum+1][3]; //讀取後存放在此二維陣列 //逐行讀取,並將每個陣列放入到陣列中 while((line = in.readLine()) != null){ String[] temp = line.split("\t"); for(int j=0;j<temp.length;j++){ arr2[row][j] = Integer.parseInt(temp[j]); } row++; } in.close(); //顯示讀取出的陣列 for(int i=0;i<sum+1;i++){ for(int j=0;j<3;j++){ System.out.print(arr2[i][j]+"\t"); } System.out.println(); } } ``` ![](https://i.imgur.com/SuNbXmh.png) ![](https://i.imgur.com/c7rjVQu.png)