Как написать код, который печатает определенный числовой спиральный шаблон в C, используя для цикла без массива - PullRequest
0 голосов
/ 15 ноября 2018

Я хочу написать код, который получает целое число n от пользователя и печатает числа по спирали от 1 до n * n без использования массивов. выход для ввода 5

input3
output:
1 2 3
8 9 4
7 6 5

Есть ли у вас какие-либо предложения о том, как написать этот код?

EDIT: Вот код с использованием массивов:

#include <stdio.h>

int main(){
/*declaration of the variables*/
int i, j, ascendingNumbers;
int leftAndTop, rightAndBottom;
int size;
scanf("%d", &size);
int matrix[size][size];

leftAndTop = 0;
rightAndBottom = size - 1;
ascendingNumbers = 1;

/*filling the array*/
for(i = 1; i <= size/2; i++, leftAndTop++, rightAndBottom--){
    /*left to right*/
    for(j = leftAndTop; j <= rightAndBottom; j++, ascendingNumbers++){
        matrix[leftAndTop][j] = ascendingNumbers;
    }

    /*top to bottom*/
    for(j = leftAndTop + 1; j <= rightAndBottom; j++, ascendingNumbers++){
        matrix[j][rightAndBottom] = ascendingNumbers;
    }

    /*right to left*/
    for(j = rightAndBottom-1; j >= leftAndTop; j--, ascendingNumbers++){
        matrix[rightAndBottom][j] = ascendingNumbers;
    }

    /*bottom to top*/
    for(j = rightAndBottom - 1; j >= leftAndTop+1; j--, ascendingNumbers++){
        matrix[j][leftAndTop] = ascendingNumbers;
    }
}

/*fill the center for odd size*/
if(size % 2){
    matrix[leftAndTop][j + 1] = ascendingNumbers;
}

/*print*/
for(i = 0; i < size; i++){
    for(j = 0; j < size; j++){
        printf("%d  ", matrix[i][j]);
    }
    printf("\n");
}

return 0;
}

1 Ответ

0 голосов
/ 16 ноября 2018

Одно из решений состоит в том, чтобы взять код, который уже может заполнить массив спиральным узором, и поместить его во вложенный цикл, который использует этот код, чтобы найти номер для текущей позиции печати. Конечно, есть более эффективные решения, но это позволяет преобразовать решение, которое работает с массивами, в решение, которое не требует массивов.

Первая программа здесь использует массив для печати спирального рисунка чисел. Вторая программа представляет собой модифицированную версию первой, которая печатает число, когда позиция печати совпадает с позицией в спиральном цикле, а не сохраняет ее в массиве. Я оставлю это вам, чтобы посмотреть, сможете ли вы изменить существующий код для достижения этой цели.

Использование двухмерного массива:

/* A program that prints a spiral using a 2d array */

#include <stdio.h>

int main(int argc, char *argv[])
{
    int size;
    if (argc < 2 || (sscanf(argv[1], "%d", &size) != 1) || size < 1) {
        fprintf(stderr, "Usage: spiral N  [N > 0]\n");
        return 1;
    }

    int arr[size][size];
    int num_elems = size * size;


    enum Dir { RIGHT, DOWN, LEFT, UP };
    int num_directions = 4;

    int side_len = size;
    int row = 0;       // arr row index
    int col = 0;       // arr column index
    int pos = 0;       // position in a side

    // travel around the spiral to fill the array
    enum Dir direction = RIGHT;
    for (int i = 0; i < num_elems; i++) {
        arr[row][col] = i + 1;
        ++pos;

        if (pos == side_len) {                             // change direction
            direction = (direction + 1) % num_directions;
            pos = 0;

            // having changed direction, shorten side_len in two cases
            if (direction == DOWN || direction == UP) {
                --side_len;
            }
        }

        switch (direction) {
        case RIGHT:
            ++col;
            break;
        case DOWN:
            ++row;
            break;
        case LEFT:
            --col;
            break;
        case UP:
            --row;
            break;
        default:
            fprintf(stderr, "Unexpected value in switch statement\n");
            return 1;
        }
    }

    for (row = 0; row < size; row++) {
        for (col = 0; col < size; col++) {
            printf("%4d", arr[row][col]);
        }
        putchar('\n');
    }
    putchar('\n');

    return 0;
}

Использование только циклов:

/* A program that prints a spiral using loops but no arrays */

#include <stdio.h>

int main(int argc, char *argv[])
{
    int size;
    if (argc < 2 || (sscanf(argv[1], "%d", &size) != 1) || size < 0) {
        fprintf(stderr, "Usage: spiral N  [N >= 0]\n");
        return 1;
    }

    int num_elems = size * size;

    enum Dir { RIGHT, DOWN, LEFT, UP };
    int num_directions = 4;

    // loop printing positions: print a row at a time
    for (int y = 0; y < size; y++) {
        for (int x = 0; x < size; x++) {
            int side_len = size;          // length of current side
            int row = 0;                  // arr row index
            int col = 0;                  // arr column index
            int pos = 0;                  // position in a side

            // travel around spiral until printing number is reached
            enum Dir direction = RIGHT;
            for (int i = 0; i < num_elems; i++) {
                if (row == y && col == x) {  // print and escape loop
                    printf("%4d", i + 1);
                    break;
                }
                ++pos;

                if (pos == side_len) {                     // change direction
                    direction = (direction + 1) % num_directions;
                    pos = 0;

                    // having changed direction, shorten side_len in two cases
                    if (direction == DOWN || direction == UP) {
                        --side_len;
                    }
                }

                switch (direction) {
                case RIGHT:
                    ++col;
                    break;
                case DOWN:
                    ++row;
                    break;
                case LEFT:
                    --col;
                    break;
                case UP:
                    --row;
                    break;
                default:
                    fprintf(stderr, "Unexpected value in switch statement\n");
                    return 1;
                }
            }
        }
        // newline after row
        putchar('\n');
    }
    // newline after printing all numbers
    putchar('\n');

    return 0;
}

Вот несколько примеров взаимодействий со второй программой:

>$ ./spiral2 3
   1   2   3
   8   9   4
   7   6   5

>$ ./spiral2 6
   1   2   3   4   5   6
  20  21  22  23  24   7
  19  32  33  34  25   8
  18  31  36  35  26   9
  17  30  29  28  27  10
  16  15  14  13  12  11
...