1. 程式人生 > 實用技巧 >設計模式(四)之裝飾者模式

設計模式(四)之裝飾者模式

稀疏陣列:

 當一個數組(包括多維陣列)中大部分元素為0,或者為同一個值的陣列時,,為了節約空間起到壓縮的效果,將資料用另一種結構來表示,即稀疏陣列。

稀疏陣列的處理方法是:

 記錄陣列一共有幾行幾列,有多少個不同的值
 把具有不同值的元素的行列及值記錄在一個小規模的陣列中,從而縮小程式的規模

如二維陣列如下
共4行5列,其中大部分值為0,3個非0數值

{
  0   0   6   0   0
  5   0   0   9   0
  0   0   0   0   0
  0   0   0   0   0
}

轉為稀疏陣列如下
其中第一行[0][0],[0][1],[0][2]表示原始陣列的行數、列數、非0的個數
後面的3行中的每一行表示一個非0數值所在的行列及值的大小,如(0,3,6)表示原始陣列的第0行第3列的值為6

{
  4   5   3
  0   3   6
  1   0   5
  1   3   9
}

程式碼示例:

public class SparseArray {

    public static void main(String[] args) throws IOException {
        //1、建立一個二維陣列
        int[][] chessArr1 = new int[11][11];
        chessArr1[1][2] = 1 ;
        chessArr1[2][3] = 2 ;
        System.out.println("原始二維陣列:");
        //記錄非0的個數
        int sum = 0;
        for (int[] rows : chessArr1){
            for (int data : rows){
                System.out.printf("%2d ",data);
                if (data!=0)
                    sum++;
            }
            System.out.println();
        }

        //2、將二維陣列轉為稀疏陣列
        //為稀疏陣列賦值
        //賦值第0行
        int[][] sparseArr = new int[sum+1][3];
        sparseArr[0][0] = chessArr1.length;
        sparseArr[0][1] = chessArr1[0].length;
        sparseArr[0][2] = sum;
        //賦值其他行
        int count = 0;
        for (int i=0; i<chessArr1.length ; i++){
            for (int j=0; j<chessArr1[i].length;j++){
                if (chessArr1[i][j] != 0){
                    count++;
                    sparseArr[count][0] = i;
                    sparseArr[count][1] = j;
                    sparseArr[count][2] = chessArr1[i][j];

                }
            }
        }
        System.out.println("轉換為的稀疏陣列為:");
        printArray(sparseArr);

        //3、將稀疏陣列轉為二維陣列
        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];
        }
        System.out.println("轉換後的二維陣列為:");
        printArray(chessArr2);


//        saveArray(sparseArr,new File("array.csv"));
//        int[][] readArray = readArray(new File("array.csv"));
//        System.out.println("讀取檔案的稀疏列表:");
//        for (int[] line : readArray){
//            for (int data : line){
//                System.out.printf("%3d ",data);
//            }
//            System.out.println();
//        }
    }

    public static void saveArray(int[][] arr,File file) throws IOException {
        String path = SparseArray.class.getResource("").getPath().substring(1);
        File saveFile = new File(path+"\\"+file.getName());
        if (!saveFile.exists()){
            if(!saveFile.createNewFile()){
                throw new RuntimeException("建立檔案:"+saveFile+"失敗;");
            }
        }
        //寫資料
        FileWriter fw = new FileWriter(saveFile);
        for (int[] ints : arr) {
            String line = Arrays.toString(ints);
            line = line.replace(" ","");
            line = line.substring(1, line.length() - 1);
            fw.write(line + "\r\n");
        }
        fw.close();
    }


    public static int[][] readArray(File file) throws IOException {
        String path = SparseArray.class.getResource("").getPath().substring(1);
        File readFile = new File(path+"\\"+file.getName());
        if (!readFile.exists()){
           throw new RuntimeException("讀取檔案:"+readFile+"失敗,檔案不存在");
        }
        //讀取資料
        BufferedReader br = new BufferedReader(new FileReader(readFile));
        //讀取頭資訊
        String line = br.readLine();
        String[] strings = line.split(",");
        int lens = Integer.parseInt(strings[2]);
        int[][] retArray = new int[lens+1][3];
        retArray[0][0] = Integer.parseInt(strings[0]);
        retArray[0][1] = Integer.parseInt(strings[1]);
        retArray[0][2] = Integer.parseInt(strings[2]);
        //讀取頭以外的資訊
        for(int count=1;count<=lens;count++){
            line = br.readLine();
            strings = line.split(",");
            retArray[count][0] = Integer.parseInt(strings[0]);
            retArray[count][1] = Integer.parseInt(strings[1]);
            retArray[count][2] = Integer.parseInt(strings[2]);
        }
        br.close();
        return retArray;
    }

    /**
     * 列印二維陣列
     * @param array
     */
    public static void printArray(int[][] array){
        for (int[] rows : array){
            for (int data : rows){
                System.out.printf("%2d ",data);
            }
            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  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  0 
轉換為的稀疏陣列為:
11 11  2 
 1  2  1 
 2  3  2 
轉換後的二維陣列為:
 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  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  0