對面試題“輸入n,求一個nXn矩陣,規定矩陣沿45度遞增,形成一個zigzag數組(JPEG編碼裏取像素數據的排列順序),請問如何用C++實現?”的理解

void print_mat(int **mat, int mat_size)  

{  

    int i, j;  

    cout << "你輸入的" << mat_size << "階ZigZag數組爲:"  << endl << endl;  

    for(i = 0; i < mat_size; i++)  

    {  

        for (j = 0; j < mat_size; j++)  

            printf("%5d", mat[i][j]);  

        cout << endl;  

    }  

    cout << endl;  

}  

  

void fill_mat(int **mat, int mat_size)  

{  

  int squa = mat_size * mat_size;  

  int i, j, s;  

  for (i = 0; i < mat_size; i++)  

    for (j = 0; j < mat_size; j++)  

    {  

      s = i + j;  

      if (s < mat_size)  

        mat[i][j] = s * (s + 1) / 2 + (((i + j) % 2) ? i : j);  

      else  

      {  

        s = (mat_size - 1 - i) + (mat_size - 1 - j);  

        mat[i][j] = squa - s * (s + 1) / 2 - (mat_size - ((( i + j) % 2) ? i : j));  

      }  

    }  

}  

 

 

以上代碼抄自網上

 

 

首先以自左下角向右上角進行了對角線劃分

 

我們爲了按行輸出,所以讓s=i+j,找出數字與行列數值的關係

 

分爲兩種情況:

一種在對角線左上(n<N):

利用s(s+1)/2可以求出每個行列的值在該值所在斜線中的最小數字;

 

然後分爲右上的增加和左上的增加,所以根據行列和對2求餘判斷奇偶,奇的話爲右上的增加,所以我們加上行列值取增加的列,偶的話爲左下的增加,所以我們加上行列值取增加的行

 

 mat[i][j] = s * (s + 1) / 2 + (((i + j) % 2) ? i : j);  

 

 

一種在對角線右下(n>N)

這種比較複雜,因爲這面的數據是隨着每個斜線的的遞減,是左上面的逆過程,

通過 s = (mat_size - 1 - i) + (mat_size - 1 - j);  求出斜線左上方對稱的斜線的最小值,就如:55斜線對應44斜線

 

 

然後通過s(s+1)/2求出該斜線最小值,如36

 

mat[i][j] = squa - s * (s + 1) / 2 - (mat_size - ((( i + j) % 2) ? i : j));  

 

我們求出的這個36後怎麼和55有什麼關係呢

 

squa=N*N

 

爲總數,然後我們利用總數減去對稱斜線最小數求出我們這行斜線最大數

 

就像100減去36,我們得出64就是55所在斜線最大值,然後再利用距離最大值的位置(mat_size - ((( i + j) % 2) ? i : j))得出該值

 

 

 

其實我比較想知道這個zigzag數組是什麼,有什麼用。。。爲什麼jpeg編碼要這樣呢

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章