Транспонировать матрицу с помощью указателя в C - PullRequest
0 голосов
/ 28 февраля 2019

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

Спасибо за вашу помощь!

Ответы [ 3 ]

0 голосов
/ 28 февраля 2019

У вас есть проблема с определением места в памяти для строки и столбца каждой ячейки. Вот способ их использования:

i-th rows of transpose = *(transpose + i)
j-th col in i-th row of transpose  = *(*(transpose+i) + j)

Аналогично матрице:

i-th rows of matrix= *(matrix + i)
j-th col in i-th row of matrix  = *(*(matrix+i) + j)

Так вот мойрешение:

void transposeMatrix(int matrix[ROWS][COLS]) {
    int**  transpose = (int **)malloc(ROWS * sizeof(int*));
    for (int i = 0; i < ROWS; i++)
        transpose[i] = (int*)malloc(COLS * sizeof(int));

    for (int i = 0; i < ROWS; i++) {
        puts("");
        for (int j = 0; j < COLS; j++) {
            *(*(transpose + i) + j) = *(*(matrix + j) + i);
            printf("%d ", transpose[i][j]);
        }
        puts("");
    }
}
0 голосов
/ 28 февраля 2019

Вам не обязательно выделять новую матрицу строка за строкой.Кроме того, функции, которые выполняют транспонирование и печать, могут передаваться прямо int *, а не предварительно сформированными массивами, такими как int [3][2] и т. Д.

Возможно даже изменить форму матрицы на месте (т.е. без выделения нового пространства).Если хотите, я могу опубликовать пример кода для этого позже.

Например:

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

int M[2][3] = { {1, 2, 3}, {7, 8, 9} };
int N[3][3] = { {1, 2, 3}, { 4, 5, 6 }, {7, 8, 9} };


int *alloc_transpose(const int *matrix, size_t rows, size_t cols);
void print_matrix(const int *matrix, size_t rows, size_t cols);

int main()
{
    int *t_matrix;
    print_matrix(&M[0][0], 2, 3);
fprintf(stderr, "----\n");
    t_matrix = alloc_transpose(&M[0][0], 2, 3);
    if (t_matrix) {
        print_matrix(t_matrix, 3, 2);
    }
    free(t_matrix);
    t_matrix = alloc_transpose(&N[0][0], 3, 3);
    if (t_matrix) {
    fprintf(stderr, "----\n");
        print_matrix(t_matrix, 3, 3);
    }
    free(t_matrix);
    return 0;
}

void print_matrix(const int *matrix, size_t rows, size_t cols)
{
    size_t r, c;
    for (r = 0; r < rows; r++) {
        for (c = 0; c < cols; c++) {
            printf("%d ", *((matrix + r * cols) + c));
        }
        putchar('\n');
    }
}

int *alloc_transpose(const int *matrix, size_t rows, size_t cols)
{
    int *tm;
    int r, c;       /* relative to transposed matrix */

    tm = malloc(sizeof(int) * cols * rows); /* contiguous is okay */

    if (!tm)
        return NULL;

    for (r = 0; r < rows; r++) {
        for (c = 0; c < cols; c++) {
            *((tm + c * rows) + r) =
                          *((matrix + r * cols) + c);
        }
    }

    return tm;
}
0 голосов
/ 28 февраля 2019

*(transpose+i*ROWS+j) - неправильный способ доступа к элементам массива указателей.Это способ доступа к 2-мерному массиву, который хранится непрерывно в главном порядке строк в массиве int[] или через указатель int*.

Способ доступа к элементу 2-мерного массиваэто реализовано как массив указателей с *(*(transpose + i)+j).*(transpose + i) возвращает указатель на строку i, добавляя j к нему, возвращающему адрес j-го столбца в строке, и отсылку, которая получает или устанавливает значение.

Это будеттакже работать с массивом, объявленным как

int matrix[ROWS][COLS];

из-за того, как массивы распадаются на указатели.

Таким образом, ваша строка назначения должна быть:

        *(*(transpose + i)+j) = *(*(matrix + j)+i);

Тогда вам нужноизменить строку printf(), потому что она не печатает тот же элемент, который вы только что присвоили.Должно быть:

        printf("%d ", transpose[i][j]);

Полная рабочая функция:

void transposeMatrix(int matrix[ROWS][COLS]){
    int**  transpose=(int **)malloc(ROWS*sizeof(int*));
    for(int  i=0; i< ROWS; i++)
        transpose[i]=(int*)malloc(COLS*sizeof(int));

    for(int  i=0; i<ROWS;i++){
        puts("");
        for(int  j=0; j<COLS;j++){
            *(*(transpose + i)+j) = *(*(matrix + j)+i);
            printf("%d ",transpose[i][j]);
        }
        puts("");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...