關於迴旋矩陣的幾點思考
(數組-不使用數組)
某日,友人出題,要求 N*N的迴旋矩陣的輸出。
迴旋矩陣,顧名思義,就是從外圈數字由大到小旋轉到內圈的N階矩陣
例如 :
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
便是一個5*5的迴旋矩陣。
對於這類問題,首先想到的是通過數組進行輸出,現在數組中對各個位置的數進行排列,再由for迴圈對數組進行輸出操作。如此思路清晰,代碼明了,也不易出錯。
#include <stdio.h>
#define N 16 //在此定義 矩陣的大小
int main(int argc, const char * argv[])
{
int a[N][N] = {0};
int i ,j ,x ,y ,m = 0; //左x 右y
//計算部分
for ( x = 0 ; x < N / 2 ; x++) { //x是下限
y = N - x - 1; // y是上限
if ( m == N * N) {
break;
}
for ( i = x ; i < y ; i++) {
m++;
a[i][x] = m;
}
if ( m == N * N) {
break;
}
for ( i = x ; i < y ; i++ ) {
m++;
a[y][i] = m;
}
if ( m == N * N) {
break;
}
for ( j = y ; j > x ; j-- ){
m++;
a[j][y] = m;
}
if ( m == N * N) {
break;
}
for ( j = y ; j > x ; j-- ){
m++;
a[x][j] = m;
}
}
if ( N % 2 != 0) {
int r = N / 2 ;
a[r][r] = N * N; //判讀是否奇數 消除以上打表方法的小BUG
}
//列印部分
for (i = 0 ; i < N ; i++) {
for ( j = 0 ; j < N ; j++) {
printf("%4d ", a[j][i]);
}
printf("\n\n");
}
return 0;
}
此處使用宏定義定義階層N的值,算是偷了一點懶,若需手動錄入N的大小,可以先建一個100*100的二位元組(10*10)也可,再將讀入的數的值賦值給N,代碼幾乎相同,此處不再贅述。
此處思路是大環套小環的“嵌套”思路,即由外圈向內,逐圈進行計算,得益於數組可以先計算再輸出的所謂優點,可以先計算出每一圈各個位置的每個數之後,再進行整體的輸出。這裡的方法更將每一環切分為4小段,再對每一段上的每一個數進行填充。其中N為奇數時因為for迴圈判斷的機制,所以出現了一個Bug,導致最中心的數無法進行填充,最後通過特殊法對N進行判斷,填充了中心的缺口。最後以二重for迴圈對二維數組進行列印輸出。
這裡的方法並不是非常的好,大家肯定有更好的辦法。那麼能不能不用數組呢。辦法是有的。
#include <iostream>
#include <iomanip>
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
using namespace std;
int matrix(int i, int j, int n);
int main(int argc, const char * argv[])
{
int n, i, j;
cout << "Please input n:";
cin >> n;
for (j = 0; j < n; j++) {
for (i = 0; i < n; i++) {
cout << setw(4) <<matrix(j, i, n);
}
cout << endl <<endl;
}
return 0;
}
int matrix(int i, int j, int n)
{
int m, a, l;
m = min( min( i, n-1-i ), min( j, n-1-j ) ); //計算在第幾環
i -= m;
j -= m;