1. 程式人生 > >輸出螺旋陣列(難度:1顆星)

輸出螺旋陣列(難度:1顆星)

輸入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;
}

執行結果:

這裡寫圖片描述