У меня есть эта программа, которую я сделал, которая должна транспонировать матрицу, независимо от ее размера. Однако он работает не так, как предполагалось, и я понятия не имею, почему, я получаю вывод, что нет ошибок компиляции, но вывод для {1,2,3}, {4,5,6}, равен { 1,0,0}, {0,0,4}, что для меня абсолютно бессмысленно. Я много раз прорабатывал «снимки памяти» на бумаге, но просто не могу найти то, что мне не хватает, мне действительно просто нужен еще один взгляд, спасибо.
#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
#include <cmath>
#include <vector>
using namespace std;
void squaretranspose(int &M, int &MT, int ROWS, int COLS);
int main(void)
{
int M[2][3]={{1,2,3},{4,5,6}};
int MT[3][2]={0};
int ROWS(2),COLS(3);
int i,j;
cout << " The entries of the original matrix " << endl;
for(i=0;i<=ROWS-1;i++)
{
for(j=0;j<=COLS-1;j++)
{
cout<<M[i][j]<<"\t";
}
cout << endl;
}
squaretranspose(M[0][0],MT[0][0],ROWS,COLS);
cout << " The entries of the transposed non-square matrix " << endl;
for(i=0;i<=COLS-1;i++)
{
cout << endl;
for(j=0;j<=ROWS-1;j++)
{
cout<<MT[i][j]<<"\t";
}
}
system ("PAUSE");
return 0;
}
void squaretranspose (int &M, int &MT, int ROWS, int COLS)
{
// declare pointers to change the input matrice's values
int *ptr,*ptrT;
// declare indices for a row by row process
int i,j;
// declare placeholder 2d vectors for swapping the I,j, entries to ,j,i entries
vector < vector<int>> temp(ROWS,COLS);
vector < vector<int>> tempT(COLS,COLS);
vector < vector<int>> temp_T(ROWS,ROWS);
// set the pointers to point to the first entry of the input and output matrices
ptr = &M;
ptrT = &MT;
// if rows=cols we want to use 2d vector temp
if (ROWS=COLS)
{
// store all of the input matrice's values in the 2d vector "temp"for(i=0;i<=ROWS-1;i++)
{
for(j=0;j<=COLS-1;j++)
{
// set the i,j th entry of the 2d vector "temp" equal to the value currently pointed to by the pointer
temp[i][j]=*ptr;
// increment the pointer to the address of the next entry of the input matrix unless we are on the last entry
if ((i!=ROWS-1)&&(j!=COLS-1))
{
ptr++;
}
}
}
}
// reset pointer address to first entry
ptr=&M;
// the for loop for swapping the j,i entries of the 2d vector "temp" with the i,j entries of the input matrix
for(i=0;i<=ROWS-1;i++)
{
for(j=0;j<=COLS-1;j++)
{
// if j is not equal to i swap the value pointed to by the pointer (the i,j entry of the input matrix) for the j,ith entries value of the 2d vector "temp"if (j!=i)
{
*ptr=temp[j][i];
}
// increment the pointer if it is not on the last entry
if ((i!=ROWS-1)&&(j!=COLS-1))
{
ptr++;
}
}
}*/// if ROWS<COLS we want to have 2d vector tempT
if (ROWS<COLS)
{
// store all of the input matrice's values in the 2d vector "tempT"for(i=0;i<=ROWS-1;i++)
{
for(j=0;j<=COLS-1;j++)
{
// set the j,ith entry of the 2d vector "temp" equal to the value currently pointed to by the pointer
tempT[j][i]=*ptr;
// increment the pointer to the address of the next entry of the input matrix
if (((i!=(ROWS-1))&&(j!=(COLS-1))))
{
ptr++;
}
}
}
ptr=&M;
// transport the entries of tempT into the output matrix MT
for(i=0;i<=COLS-1;i++)
{
for(j=0;j<=ROWS-1;j++)
{
*ptrT=tempT[i][j];
// increment the pointer
if (((i!=ROWS-1)&&(j!=COLS-1)))
{
ptrT++;
}
}
}
}
ptrT=&MT;
// if ROWS>COLS we want to use the 2d vector temp_T
if (ROWS>COLS)
{
// store all of the input matrice's values in the 2d vector "temp_T"for(i=0;i<=ROWS-1;i++)
{
for(j=0;j<=COLS-1;j++)
{
// set the j,i th entry of the 2d vector "temp" equal to the value currently pointed to by the pointer
temp_T[j][i]=*ptr;
// increment the pointer
if (((i!=ROWS-1)&&(j!=COLS-1)))
{
ptrT++;
}
}
// the for loop for swapping the j,i entries of the 2d vector "temp" with the i,j entries of the input matrix
for(i=0;i<=COLS-1;i++)
{
for(j=0;j<=ROWS-1;j++)
{
// if j is not equal to i swap the value pointed to by the pointer (the i,j entry of the input matrix) for the j,ith entries value of the 2d vector "temp"if (j!=i)
{
*ptrT=temp_T[j][i];
}
// increment the pointer
if (((i!=ROWS-1)&&(j!=COLS-1)))
{
ptrT++;
}
}
}
}
return;
}
// да, это не очень эффективно, если COLS очень маленький и говорит, что ROWS очень велика из-за промежуточного вектора 2d-квадрата, но для всего остального это должно быть довольно хорошо, если он работал правильно.
Есть несколько основных проблем с вашим кодом, эта строка:
if (ROWS=COLS)
вероятно должен был быть:
if (ROWS == COLS)
В первом случае вам будет присвоено значение COLS
в ROWS
во втором случае вы будете проверять, равны ли они. Во всех ваших for
петли, которые вы используете <=
когда вы должны использовать <
в противном случае вы будете иметь доступ к одному за пределами вашего массива.
Кроме того, код слишком сложен, функция транспонирования должна быть довольно простой, это один из возможных методов:
template <int n, int m>
void squaretranspose( int a[n][m], int b[m][n])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
b[j][i] = a[i][j];
}
}
}
Но самый быстрый и простой способ транспонировать матрицу — это инвертировать ваши координаты, поэтому вместо доступа (i,j)
вы получаете доступ (j,i)
, Если с другой стороны производительность является вашей главной заботой, то это предыдущая тема освещает тему довольно хорошо, мое решение, а также мое решение, как другие, которые могут вам подойти.
Используйте индексацию DIY: ptrT[ index(j,i,COLS,ROWS) ] = ptr[ index(i,j,ROWS,COLS) ]
, Теперь все, что вам нужно сделать, это написать функцию, которая преобразует 2D-индексы в 1D-индексы.