Поменяйте местами столбцы с помощью указателей в C - PullRequest
0 голосов
/ 05 октября 2018

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

Имея следующую матрицу,я получу число, которое будет числом перестановок (число перестановок столбцов, которые будут перемещаться вправо, а последний столбец будет перемещаться в первый столбец).

Например,

Количество перестановок столбцов: 5

|1 2 3 |-----> |2 3 1 |

|3 1 2 |-----> |1 2 3 |

|2 3 1 |-----> |3 1 2 |

Я написал следующий код с использованием указателей, как вы можете видеть, я строю матрицу с многомерным массивом и присваиваю все это указателю:

short elementMatrix[3][3] = {{1, 2, 3},
                             {3, 1, 2},
                             {2, 3, 1}};
short *element_matrix;
element_matrix = *elementMatrix;

int counter = 1;
while (counter <= 5)
{
       for (int i = 0; i < 3; i++)
       {
            int temp = elementMatrix[i][PR.elem_mat_size - 1];
            *outElementMatrix = *outElementMatrix + i * PR.elem_mat_size + PR.elem_mat_size - 1;

            for (int j = 3 - 1; j >= 0; j--)
            {
               *(outElementMatrix + i * PR.elem_mat_size + j) = *(outElementMatrix + i * PR.elem_mat_size + j - 1);

                if (j == 0)
                {
                   *(outElementMatrix + i * PR.elem_mat_size + j) = *outElementMatrix;
                }
            }       
        }
   counter++;                                    
}

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

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

Я буду использовать дополнительный буферчтобы помочь со свопами.

#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <assert.h>

// rotate the values of an array using a buffer to ease the swappings
void rotate_(size_t n, void *arr, void *tmp, size_t offset)
{
    assert(n  &&  arr  &&  tmp  &&  offset <= n);
    // casting to perform pointer arithmetic
    memcpy(tmp, (char *)arr + (n - offset), offset);
    memmove((char *)arr + offset, arr, n - offset);
    memcpy(arr, tmp, offset);
}

void rotate_columns_short(size_t r, size_t c, short mat[r][c], short *buf, int n)
{
    // clamp the value of the offset to the number of columns
    size_t offset = (n >= 0
                    ? n % c
                    : c - -n % c) * sizeof(short);

    // transform each row
    for (short *row = &mat[0][0], *row_end = row + r * c;
         row != row_end;
         row += c)
    {
        rotate_(c * sizeof(short), row, buf, offset);
    }
}

void print_matrix_short(size_t r, size_t c, short mat[r][c])
{
    for (size_t i = 0; i < r; ++i)
    {
        for (size_t j = 0; j < c; ++j)
        {
            printf(" %hd", mat[i][j]);
        }
        puts("");
    }
}

#define ROWS 3
#define COLS 3

int main(void)
{
    short matrix[ROWS][COLS] = {{1, 2, 3},
                                {3, 1, 2},
                                {2, 3, 1}};
    short buf[COLS];

    print_matrix_short(ROWS, COLS, matrix);
    puts("");

    rotate_columns_short(ROWS, COLS, matrix, buf, 5);

    print_matrix_short(ROWS, COLS, matrix);

}

Вывод beeing:

 1 2 3
 3 1 2
 2 3 1

 2 3 1
 1 2 3
 3 1 2
0 голосов
/ 05 октября 2018

Поскольку вы хотите поменять столбцы, имеет смысл, чтобы указатели представляли столбцы.Таким образом, вы можете поменять местами указатель, чтобы поменять местами столбец.Итак, давайте получим массив из 3 указателей на столбец.

short* col[3];

Каждый столбец состоит из 3 short с, поэтому выделите столько памяти.

for (int i = 0; i < 3; i++) {
    col[i] = (short*)malloc(3 * sizeof(short));
}

Теперь для инициализацииМатрица.Это немного многословно, поэтому, если кто-нибудь знает лучший способ, отредактируйте его.:)

col[0][0] = 1;  col[1][0] = 2;  col[2][0] = 3;
col[0][1] = 3;  col[1][1] = 1;  col[2][1] = 2;
col[0][2] = 2;  col[1][2] = 3;  col[2][2] = 1;

Теперь мы делаем обмен.Обратите внимание, что вам нужна временная переменная, как предложил Ришикеш Радж.Также обратите внимание, что три перестановки возвращают его к оригиналу, поэтому вместо замены n раз вам нужно только поменять n % 3 раз.Конечно, это будет почти мгновенно с 5 или 2 обменами, но если вам нужно сделать как миллиард, разница должна быть заметна.

for (int i = 0; i < 5; i++) {
    short* temp = col[2];
    col[2] = col[1];
    col[1] = col[0];
    col[0] = temp;
}

Мы гарантируем, что результат будет правильным, напечатав его:

for (int i = 0; i < 3; i++) {
    printf("%d %d %d\n", col[0][i], col[1][i], col[2][i]);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...