C/C++

СИ. Можно ли как-то транспонировать матрицу, не создавая новую

СИ. Можно ли как-то транспонировать матрицу, не создавая новую
Код:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
int main(){
int **a;
int n, m;
scanf("%d", &n);
scanf("%d", &m);
a = (int**)malloc(n*m * sizeof(int));
for(int i = 0; i < n; i++) {
a[i] = (int*)malloc(m * sizeof(int*));
for(int j = 0; j < m; j++) {
scanf("%d", &a[i][j]);
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
printf("%d", a[j][i]);
printf(" ");
}
printf("\n");
}
for(int i = 0; i < n; i++){
free(a[i]);
}
free(a);
}
Canis Edit
Canis Edit
199
В массиве a всего четыре строки (n = 4): первый индекс — от 0 до 3.
И пять столбцов (m = 5): второй индекс — от 0 до 4.

При выводе транспонированной матрицы вы меняете i от 0 до n; j — от 0 до m.
То есть j меняется от 0 до 4 включительно.

Однако при выводе идет вот это:
 printf("%d", a[j][i]); 
Переменная j, которая от 0 до 4, идет в первый индекс, который может быть лишь от 0 до 3.
Когда дело доходит до j = 4, происходит ошибка выхода за пределы массива.

Вы можете видеть, что у вашей программы код выхода не равен нулю (последняя строчка).
То есть что-то пошло не так.
Игорь Панин
Игорь Панин
94 880
Лучший ответ
Если надо это сделать физически, то можно, но только с квадратной матрицей и при помощи очень хитромудрого алгоритма, который будет переносить значения по кругу.
Но если физически переносить значения не нужно, можно просто поменять свое отношение к ним, как сказано выше.
Антон Горвиц
Антон Горвиц
59 043
Можно. Если элементы размещать в линейном массиве. Как? Будет время попробую
Евгенич *
Евгенич *
21 700
Евгенич * int MatrA[12]= {1,2,3,4,5,6,7,8,9,10,11,12};
int col= 4, row= 3;

for (int r= 0; r< row; r++)
{
for (int c= 0; c< col; c++)
{
printf("%d\t", MatrA[r*col+c]);
}
printf("\n");
}

printf("\n");

for (int c= 0; c< col; c++)
{
for (int r= 0; r< row; r++)
{
printf("%d\t", MatrA[r*col+c]);
}
printf("\n");
}
Евгенич * это просто вывод. Перемещение физическое сложнее чуть-чуть, но пора спать уже
malloc.h не пиши, malloc входит в stdlib.h

А вторую матрицу создавать всё равно нужно.
Не нужную матрицу удаляй.
Без новой матрицы возможно транспонировать только квадратную матрицу.

Вот как я реализовал транспонирование матриц(не только квадратных):
 #include   
#include

struct _mat_t
{
float **data;

size_t rows, columns;
};

typedef struct _mat_t * mat_t;

static mat_t new_matrix(size_t rows, size_t columns)
{
mat_t mat = malloc(sizeof(struct _mat_t));
mat->data = calloc(rows, sizeof(float));

for (size_t i = 0; i < rows; i++)
{
mat->data[i] = calloc(columns, sizeof(float));

for (size_t j = 0; j < columns; j++)
mat->data[i][j] = 0;
}

mat->columns = columns;
mat->rows = rows;

return mat;
}

static void destroy_matrix(mat_t matrix)
{
for (size_t i = 0; i < matrix->rows; i++)
free(matrix->data[i]);

free(matrix->data);
free(matrix);
}

static void show_matrix(const mat_t matrix)
{
for (size_t i = 0; i < matrix->rows; i++)
{
for (size_t j = 0; j < matrix->columns; j++)
printf("%f ", matrix->data[i][j]);

printf("\n");
}
}

static void fill_matrix(mat_t matrix)
{
for (size_t i = 0; i < matrix->rows; i++)
{
for (size_t j = 0; j < matrix->columns; j++)
scanf("%f", matrix->data[i] + j);
}
}

static void transpose_matrix(mat_t *matrix)
{
size_t n_rows = (*matrix)->columns,
n_columns = (*matrix)->rows;

mat_t old_mat = *matrix;
mat_t new_mat = new_matrix(n_rows, n_columns);

for (size_t i = 0; i < n_rows; i++)
{
for (size_t j = 0; j < n_columns; j++)
new_mat->data[i][j] = old_mat->data[j][i];
}

destroy_matrix(old_mat);

*matrix = new_mat;
}

int main(void)
{
size_t rows, columns;

printf("Rows: ");
scanf("%ld", &rows);

printf("Columns: ");
scanf("%ld", &columns);

mat_t matrix = new_matrix(rows, columns);

printf("Enter matrix values:\n");
fill_matrix(matrix);

printf("Transposed matrix:\n");
transpose_matrix(&matrix);
show_matrix(matrix);
destroy_matrix(matrix);
}

// Rows: 4
// Columns: 2
// Enter matrix values:
// 2 8
// 9 9
// 7 5
// 3 6
// Transposed matrix:
// 2.000000 9.000000 7.000000 3.000000
// 8.000000 9.000000 5.000000 6.000000