當一個數組中大部分元素爲0,或者爲同一個值的數組時,可以使用稀疏數組來保存該數組。
1、稀疏數組的處理方法:
(1)、記錄數組一共有幾行幾列,有多少個不同的值;
(2)、把具有不同值的元素的行列及值記錄在一個小規模的數組中,從而縮小程序的規模。
(3)、稀疏數組只有3列,分別爲 行、列、值。且其第一行爲原二維數組的總行數、總列數及有效數據個數的總數。
圖一是一個二維數組,圖二是創建的稀疏數組
2、如何應用?
【二維數組轉稀疏數組】
①、先遍歷二維數組,得到有效個數sum;
②、根據sum,創建稀疏數組 sparseArr int [sum+1] [3];
③、將二維數組的有效數據存入sparseArr中。
【稀疏數組轉二維數組】
①、先讀取稀疏數組第一行,根據第一行的數據,創建二維數組(已知行和列總數);
②、再讀取稀疏數組的後幾行數據,並賦給二維數組。
下面我們根據五子棋的例子,具體應用:
如圖所示:這是一個五子棋盤
使用二維數組記錄棋盤:
具體代碼:
package com.ycx.sparsearry;
public class SparseArr {
public static void main(String[] args) {
//創建一個原始的數組 11*11
// 0:表示沒有棋子 1:表示黑色棋子 2:表示藍色棋子
int[][] chessArr= new int[11][11];
chessArr[1][2] = 1;
chessArr[2][3] = 2;
//輸出原始的二維數組
System.out.println("原始二維數組:");
for (int[] row : chessArr) { //遍歷出來先是一維數組 取到了每一行
for (int data :row) { //取到了每一個數據
System.out.printf("%d\t",data);
//格式化輸出 注意是printf
}
System.out.println();
}
//一、將二維數組 轉 稀疏數組
//1.遍歷二維數組 得到非0數據的個數
int sum=0;
for (int i = 0; i <11 ; i++) {
for (int j = 0; j <11 ; j++) {
if(chessArr[i][j]!=0){
sum++;
}
}
}
System.out.println("sum=" + sum);
//2.創建對應的稀疏數組
int[][] sparesArr = new int[sum+1][3];
//給稀疏數組賦值
sparesArr[0][0]=11; //第1行第1列:原二維數組的行數
sparesArr[0][1]=11;//第1行第2列:原二維數組的列數
sparesArr[0][2]=sum;//第1行第3列:不同值總個數
//遍歷二維數組,將非0的數存到稀疏數組中
int count=0; // 記錄出現的第幾個非0個數
for (int i = 0; i <11 ; i++) {
for (int j = 0; j <11 ; j++) {
if(chessArr[i][j]!=0){ //非0數據 稀疏數組有3列: 行 列 值(如果不理解,就看筆記上的圖)
count++;
sparesArr[count][0]=i; //它在稀疏數組中的第1列是在原二維數組的行 :所以是i
sparesArr[count][1]=j;//第2列是在原二維數組的列 :所以是j
sparesArr[count][2]=chessArr[i][j];//第三列爲這個值本身
}
}
}
// 輸出稀疏數組形式
System.out.println();
System.out.println("得到的稀疏數組爲:");
for (int i = 0; i <sparesArr.length ; i++) {
System.out.printf("%d\t%d\t%d\t\n",sparesArr[i][0],sparesArr[i][1],sparesArr[i][2]);
//格式化輸出 所在行的第1、2、3列
}
System.out.println();
//二、將稀疏數組恢復成二維數組
/*
1.先讀取二維數組的第一行數據,根據第一行數據,創建原始的二維數組,比如 chessArr2=int[11][11];
2.在讀取稀疏數組後幾行的數據,並賦給原始的二維數組即可。
*/
//1.先讀取二維數組的第一行數據(原二維數組的行和列)
int r=sparesArr[0][0];
int c=sparesArr[0][1];
int[][] chessArr2 = new int[r][c]; //創建原始的二維數組
//2.在讀取稀疏數組後幾行的數據,並賦給原始的二維數組
//因爲第一行是原數組的行列及有效數據的個數,所以從第二行開始,即i=1
for (int i = 1; i <sparesArr.length ; i++) {
int r1=sparesArr[i][0];//稀疏數組第1列爲有效數據在原二維數組中的行
int r2=sparesArr[i][1];//稀疏數組第2列爲有效數據在原二維數組中的列
chessArr2[r1][r2]=sparesArr[i][2];//稀疏數組第3列爲有效數據的值
}
//輸出恢復後的二維數組
System.out.println();
System.out.println("恢復後的二維數組爲:");
for (int[] row : chessArr) {
for (int data :row) {
System.out.printf("%d\t",data);
}
System.out.println();
}
}
}
運行結果: