輸出螺旋陣列(難度:1顆星)
阿新 • • 發佈:2019-01-31
輸入n*n矩陣的n值,打印出一個螺旋矩陣,如下面例子:
當n= 5時,輸出
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
方法1:
用靜態的二維陣列儲存,到方法2在動態生成,隨著n的變化而變化,根據右,下,左,上的順序,就可以走出一個螺旋陣列。
參考程式碼:
#include <stdio.h>
int arr[100][100], n;//暫時先用靜態的二維陣列儲存,到方法2 在動態生成,隨著n的變化而變化
enum EmDir
{
emRight = 1,
emDown = 2,
emLeft = 3,
emUp = 4,
};
int IsRightDirOk(int row, int column)
{
return (column + 1 < n && 0 == arr[row][column + 1]);
}
int IsDownDirOk(int row, int column)
{
return (row + 1 < n && 0 == arr[row + 1 ][column]);
}
int IsLeftDirOk(int row, int column)
{
return (column - 1 >= 0 && 0 == arr[row][column - 1]);
}
int IsUpDirOk(int row, int column)
{
return (row - 1 >= 0 && 0 == arr[row - 1][column]);
}
int GetNextStepDir(int curDir, int row, int column)
{
if (curDir == emRight)
return IsRightDirOk(row, column) ? emRight : emDown;
else if (curDir == emDown)
return IsDownDirOk(row, column) ? emDown : emLeft;
else if (curDir == emLeft)
return IsLeftDirOk(row, column) ? emLeft : emUp;
return IsUpDirOk(row, column) ? emUp : emRight;
}
int main()
{
int i, j, row = 0, column = 0, nCount = 1, curDir = (int)emRight;
printf("輸入n*n矩陣的n值:");
scanf_s("%d", &n);
while (nCount <= n * n)
{
arr[row][column] = nCount++;
curDir = GetNextStepDir(curDir, row, column);
if (emRight == curDir)
column++;
else if (emDown == curDir)
row++;
else if (emLeft == curDir)
column--;
else
row--;
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf("%5d", arr[i][j]);
printf("\n");
}
return 0;
}
方法2:
與方法1一樣,只是為了適應變化的n值,採用了動態分配二維陣列的空間。
參考程式碼:
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
int **pArray, n;//用一個二級指標來索引二維陣列中的元素
enum EmDir
{
emRight = 1,
emDown = 2,
emLeft = 3,
emUp = 4,
};
int IsRightDirOk(int row, int column)
{
return (column + 1 < n && 0 == pArray[row][column + 1]);
}
int IsDownDirOk(int row, int column)
{
return (row + 1 < n && 0 == pArray[row + 1][column]);
}
int IsLeftDirOk(int row, int column)
{
return (column - 1 >= 0 && 0 == pArray[row][column - 1]);
}
int IsUpDirOk(int row, int column)
{
return (row - 1 >= 0 && 0 == pArray[row - 1][column]);
}
int GetNextStepDir(int curDir, int row, int column)
{
if (curDir == emRight)
return IsRightDirOk(row, column) ? emRight : emDown;
else if (curDir == emDown)
return IsDownDirOk(row, column) ? emDown : emLeft;
else if (curDir == emLeft)
return IsLeftDirOk(row, column) ? emLeft : emUp;
return IsUpDirOk(row, column) ? emUp : emRight;
}
int main()
{
int i, j, row = 0, column = 0, nCount = 1, curDir = (int)emRight;
printf("輸入n*n矩陣的n值:");
scanf_s("%d", &n);
pArray = (int**)malloc(n * sizeof(int*));//生成n個指標,然後讓每個指標指向一段連續的大小為n * sizeof(int)的空間
for (i = 0; i < n; i++)
pArray[i] = (int*)malloc(n * sizeof(int));
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
pArray[i][j] = 0;//初始化二維陣列
while (nCount <= n * n)
{
pArray[row][column] = nCount++;
curDir = GetNextStepDir(curDir, row, column);
if (emRight == curDir)
column++;
else if (emDown == curDir)
row++;
else if (emLeft == curDir)
column--;
else
row--;
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf("%5d", pArray[i][j]);
printf("\n");
}
for (i = 0; i < n; i++)
free(pArray[i]);
free(pArray);
return 0;
}
方法3:
根據規律,列印螺旋矩形的時候,每走一圈,上下左右就分別往裡面縮小了1。
參考程式碼:
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
int **pArray, n;//用一個二級指標來索引二維陣列中的元素
int main()
{
int i, j, nCount = 1;
printf("輸入n*n矩陣的n值:");
scanf_s("%d", &n);
pArray = (int**)malloc(n * sizeof(int*));//生成n個指標,然後讓每個指標指向一段連續的大小為n*sizeof(int)的空間
for (i = 0; i < n; i++)
pArray[i] = (int*)malloc(n * sizeof(int));
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
pArray[i][j] = 0;//初始化二維陣列
for (i = 0; i <= n / 2; i++)
{
for (j = 0; j < n - i; j++)
if (0 == pArray[i][j])
pArray[i][j] = nCount++;
for (j = i + 1; j < n - i; j++)
if (0 == pArray[j][n - i - 1])
pArray[j][n - i - 1] = nCount++;
for (j = n - i - 1; j > i; j--)
if (0 == pArray[n - i - 1][j])
pArray[n - i - 1][j] = nCount++;
for (j = n - i - 1; j > i; j--)
{
if (0 == pArray[j][i])
pArray[j][i] = nCount++;
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf("%5d", pArray[i][j]);
printf("\n");
}
for (i = 0; i < n; i++)
free(pArray[i]);
free(pArray);
return 0;
}
方法4:
不利用陣列是否為0來進行判斷,而是用了4個變數來儲存4個邊界。
參考程式碼:
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#define DIR_RIGHT 0
#define DIR_DOWN 1
#define DIR_LEFT 2
#define DIR_UP 3
int **pArray, n;//用一個二級指標來索引二維陣列中的元素
int main()
{
int i, j, row = 0, column = 0, nCount = 1, nRightBound, nLeftBound, nUpBound, nDownBound, CurDir = DIR_RIGHT;
printf("輸入n*n矩陣的n值:");
scanf_s("%d", &n);
nRightBound = nDownBound = n - 1;
nLeftBound = 0;
nUpBound = 1;//上邊界的初始值要設為1,因為第一次走到的時候,已經走完一圈了
pArray = (int**)malloc(n * sizeof(int*));//生成n個指標,然後讓每個指標指向一段連續的大小為n*sizeof(int)的空間
for (i = 0; i < n; i++)
pArray[i] = (int*)malloc(n * sizeof(int));
pArray[0][0] = nCount++;
while (nCount <= n * n)
{
if (DIR_RIGHT == CurDir)
{
if (column + 1 <= nRightBound)
pArray[row][++column] = nCount++;
else
{
CurDir = (CurDir + 1) % 4;
nRightBound--;
}
}
else if (DIR_DOWN == CurDir)
{
if (row + 1 <= nDownBound)
pArray[++row][column] = nCount++;
else
{
CurDir = (CurDir + 1) % 4;
nDownBound--;
}
}
else if (DIR_LEFT == CurDir)
{
if (column - 1 >= nLeftBound)
pArray[row][--column] = nCount++;
else
{
CurDir = (CurDir + 1) % 4;
nLeftBound++;
}
}
else
{
if (row - 1 >= nUpBound)
pArray[--row][column] = nCount++;
else
{
CurDir = (CurDir + 1) % 4;
nUpBound++;
}
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
printf("%5d", pArray[i][j]);
printf("\n");
}
for (i = 0; i < n; i++)
free(pArray[i]);
free(pArray);
return 0;
}
方法5:
和方法4的區別在於,不再使用二維陣列,而是直接利用游標的位置來進行列印。
#include <stdio.h>
#include <Windows.h>
#define DIR_RIGHT 0
#define DIR_DOWN 1
#define DIR_LEFT 2
#define DIR_UP 3
void setcursor(int x,int y)
{
HANDLE hCon=GetStdHandle(STD_OUTPUT_HANDLE);
COORD setps;
setps.X=x; setps.Y=y;
SetConsoleCursorPosition(hCon,setps);
}
int main()
{//思路:不用陣列,採用控制游標的方式輸出
int n, row = 0, column = 0, nCount = 1, nRightBound, nLeftBound, nUpBound, nDownBound, CurDir = DIR_RIGHT;
printf("輸入n*n矩陣的n值:");
scanf_s("%d", &n);
nRightBound = nDownBound = n - 1;
nLeftBound = 0;
nUpBound = 1;//上邊界的初始值要設為1,因為第一次走到的時候,已經走完一圈了
printf("%5d", nCount++);
while (nCount <= n * n)
{
if (DIR_RIGHT == CurDir)
{
if (column + 1 <= nRightBound)
{
column++;
setcursor(5 * column, 1 + row);
printf("%5d", nCount++);
}
else
{
CurDir = (CurDir + 1) % 4;
nRightBound--;
}
}
else if (DIR_DOWN == CurDir)
{
if (row + 1 <= nDownBound)
{
row++;
setcursor(5 * column, 1 + row);
printf("%5d", nCount++);
}
else
{
CurDir = (CurDir + 1) % 4;
nDownBound--;
}
}
else if (DIR_LEFT == CurDir)
{
if (column - 1 >= nLeftBound)
{
column--;
setcursor(5 * column, 1 + row);
printf("%5d", nCount++);
}
else
{
CurDir = (CurDir + 1) % 4;
nLeftBound++;
}
}
else
{
if (row - 1 >= nUpBound)
{
row--;
setcursor(5 * column, 1 + row);
printf("%5d", nCount++);
}
else
{
CurDir = (CurDir + 1) % 4;
nUpBound++;
}
}
}
setcursor(0, n);
printf("\n");
return 0;
}
執行結果: