java資料結構與演算法一:稀疏陣列
阿新 • • 發佈:2020-07-28
稀疏陣列
ps:記錄韓順平資料結構與演算法
一、需求分析
因為二維陣列的很多值是預設值0,因此記錄了很多沒有意義的資料,可採用稀疏陣列解決此問題。
二、基本介紹
當一個數組中大部分元素為0,或者為同一個值的陣列時,可以使用稀疏陣列來儲存該陣列。
稀疏陣列的處理方法是:
1)記錄陣列一共有幾行幾列,有多少個不同的值
2)把具體 不同值得元素的行列及值記錄在一個小規模的陣列中,從而縮小程式的規模
稀疏陣列中第一行依次存放著總行數、總列數、 不同值的個數,其他行則依次存放著值所在的行、值所在的列、值的大小
三、二維陣列與稀疏陣列轉換的思路
二維陣列轉稀疏陣列的思路:
1、遍歷原始的二維陣列,得到有效資料的個數sum
2、根據sum就可以建立稀疏陣列sparseArr int[sum+1][3]
3、將二維陣列的有效資料存入到稀疏陣列中
稀疏陣列轉原始的二維陣列的思路
1、先讀取稀疏陣列的第一行,根據第一行的資料,建立原始的二維陣列,比如 chessArr2 = int[11][11]
2、在讀取稀疏陣列後幾行的資料,並賦給原始的二維陣列即可
四、程式碼實現
public class SparseArray { public static void main(String[] args) { //建立一個原始的二維陣列11*11 //0:表示沒有棋子,1表示黑子 2表示藍子 int chessArr1[][] = new int[11][11]; chessArr1[1][2] = 1; chessArr1[2][3] = 2; chessArr1[6][6] = 6; //輸出原始的二維陣列 System.out.println("原始的二維陣列~"); for (int[] row : chessArr1) { for(int data : row) { System.out.print(data + "\t"); } System.out.println(); } //將二維陣列 轉 稀疏陣列的思路 //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++; } } } //2.建立對應的稀疏陣列 int sparseArr[][] = new int[sum+1][3]; // 給稀疏陣列賦值 sparseArr[0][0] = 11; sparseArr[0][1] = 11; sparseArr[0][2] = sum; // 遍歷二維陣列,將非0的值存放在稀疏陣列sparseArr中 int count = 0; //count 用於記錄是第幾個非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]; } } } //輸出稀疏陣列的形式 System.out.println(); System.out.println("得到稀疏陣列為~"); for (int i = 0; i < sparseArr.length; i++) { System.out.printf("%d\t%d\t%d\t",sparseArr[i][0],sparseArr[i][1],sparseArr[i][2]); System.out.println(); } System.out.println(); //將稀疏陣列 --> 恢復成原始的二維陣列 /** * 1、先讀取稀疏陣列的第一行,根據第一行的資料,建立原始的二維陣列,比如上面的 chessArr2 = int[11][11] * 2、再讀取稀疏陣列後幾行的資料,並賦給原始的二維陣列即可 */ //1、先讀取稀疏陣列的第一行,根據第一行的資料,建立原始的二維陣列 int chessArr2[][] = new int[sparseArr[0][0]][sparseArr[0][1]]; //2、再讀取稀疏陣列後幾行的資料(從第二行開始),並賦給原始的二維陣列即可 for(int i = 1; i < sparseArr.length; i++) { chessArr2[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2]; } // 輸出恢復後的二維陣列 System.out.println(); System.out.println("恢復後的二維陣列"); for (int[] row : chessArr2) { for(int data : row) { System.out.print(data + "\t"); } System.out.println(); } System.out.println("將稀疏陣列儲存到磁碟上,比如map.data-----------"); try { File file = new File("H:\\workplaces\\eclipse_programs\\DataStructures\\map.data"); FileOutputStream fos = new FileOutputStream(file); OutputStreamWriter opsw = new OutputStreamWriter(fos,"UTF-8"); System.out.println("正在寫入......."); for (int i = 0; i < sparseArr.length; i++) { opsw.append(sparseArr[i][0] + "," + sparseArr[i][1] + "," + sparseArr[i][2] + ","); } //關閉輸出流 opsw.close(); fos.close(); System.out.println("寫入磁碟成功...."); //讀取磁碟檔案中的map.data System.out.println("正在讀取中....."); FileInputStream fs = new FileInputStream(file); InputStreamReader isr = new InputStreamReader(fs); StringBuffer sb = new StringBuffer(); while(isr.ready()) { // 讀取資料並轉成char加到StringBuffer物件中 sb.append((char)isr.read()); } // 關閉輸入流 isr.close(); fs.close(); System.out.println("讀取成功...."); String content = sb.toString(); System.out.printf("從磁碟讀取的字串為:\n%s\n",content); // 恢復稀疏陣列 String[] strArr = sb.toString().split(","); // 建立新的稀疏陣列 int[][] newSparseArr = new int[strArr.length/3][3]; int j = 0; for(String s : strArr) { newSparseArr[j/3][j%3] = Integer.parseInt(s); j++; } System.out.println("恢復後的稀疏陣列--------"); for (int i = 0; i < newSparseArr.length; i++) { System.out.printf("%d\t%d\t%d\t",newSparseArr[i][0],newSparseArr[i][1],newSparseArr[i][2]); System.out.println(); } // 恢復為原始的二維陣列 int[][] newChessArr = new int[newSparseArr[0][0]][newSparseArr[0][1]]; for(int i = 1; i < newSparseArr.length; i++) { newChessArr[newSparseArr[i][0]][newSparseArr[i][1]] = newSparseArr[i][2]; } System.out.println("恢復的原始二維陣列-------"); for(int[] row : newChessArr) { for(int data : row) { System.out.print(data + "\t"); } System.out.println(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }