Циклический сдвиг элементов матрицы

633
02 мая 2017, 07:29

Нужно осуществить циклический сдвиг элементов квадратной матрицы размерности MxN вправо на k элементов таким образом: элементы 1-й строки сдвигаются в последний столбец сверху вниз, из него - в последнюю строку справа налево, из нее - в первый столбец снизу вверх, их него - в первую строку; для остальных элементов аналогично.

C/C++

Как это реализовать общим видом,чтобы работало для любой размерность ?

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#define N 8
int main()
{
    int spiral[N][N], Step, cur[4 * (N - 1)], shift[4 * (N - 1)];
    int i, j, k, c, edge;
    //инициализация массива числами от 1 до 20
    srand(time(NULL));
    printf("Original array:\n");
    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++)
        {
            spiral[i][j] = rand() % 20 + 1;
            printf("a[%d][%d]=%d", i, j, spiral[i][j]);
        }
        printf("\n");
    }
    //запрос количества шагов поворота
    printf("\nHow many steps to turn? Step = ");
    scanf("%d", &Step);
    for (k = 0; k < N / 2; k++) //слои
    {
        edge = N - 1 - k;
        //снять слой
        c = 0;
        for (j = k; j < edge; j++)
        {
            cur[c] = spiral[k][j];
            c++;
        }
        for (i = k; i < edge; i++)
        {
            cur[c] = spiral[i][edge];
            c++;
        }
        for (j = edge; j >= k; j--)
        {
            cur[c] = spiral[edge][j];
            c++;
        }
        for (i = edge - 1; i > k; i--)
        {
            cur[c] = spiral[i][k];
            c++;
        }
        //переставить
        for (i = 0; i < 4 * (N - 2 * k - 1); i++)
            shift[(i + Step) % (4 * (N - 2 * k - 1))] = cur[i];
        //одеть слой
        c = 0;
        for (j = k; j < edge; j++)
        {
            spiral[k][j] = shift[c];
            c++;
        }
        for (i = k; i < edge; i++)
        {
            spiral[i][edge] = shift[c];
            c++;
        }
        for (j = edge; j >= k; j--)
        {
            spiral[edge][j] = shift[c];
            c++;
        }
        for (i = edge - 1; i > k; i--)
        {
            spiral[i][k] = shift[c];
            c++;
        }
    }//for - переход на следующий слой
    //Результат
    printf("Result:\n");
    for (i = 0; i < N; i++)
    {
        for (j = 0; j < N; j++) printf("%6d", spiral[i][j]);
        printf("\n");
    }
    getch();
    return 0;
}

Работает только для N константы ,как вводить это N с клаввиатуры.Если тупо выше объявить и ввести - ругается

Answer 1

Алгоритмов циклического сдвига линейной последовательности - штук пять-шесть на выбор. А организовать пересчет линейных индексов в индексы соответствующего "кольца" в вашей матрице - труда не составит. Задача решена.

Более интересным (хотя, возможно, неоправданно более громоздким) С++ решением будет реализация собственного итератора, умеющего итерировать по "кольцу" матрицы, который затем можно просто использовать в std::rotate.

READ ALSO
Работа с QSortFilterProxyModel

Работа с QSortFilterProxyModel

Есть QStringListModel и QSortFilterProxyModel с соответствующими представлениями, а также QLineEditтакже есть:

290
Сортировка множеством

Сортировка множеством

У меня есть некоторая неупорядоченная последовательность пар целых чисел std::pair<int, int>Если все элементы этой последовательности добавить...

232
Как организовать JavaScript код?

Как организовать JavaScript код?

Как организовать JavaScript код если я пишу не SPA, а только лишь слайдер, валидатор форм и прочие мелочи? И то это всё сторонние плагины которые...

236
Как поделить число нацело в javascript?

Как поделить число нацело в javascript?

Поделить на число без остатка в JS можно несколькоми способами

441