我想编写一个程序来转置一个n * n矩阵,但代码输出有线。它没有转置矩阵。假设我想转置一个矩阵{(1,2,3),{4,5,6),(7,8,9)},结果基本上和原来的一样有一些奇怪的行为,我有不知道。
#include<iostream>
#include<iomanip>
using namespace std;
void transpose(int* p, int n);
#define M 20
int main()
{
int a[M][M];
int n;
int* p;
cout << "The size of a matrix is: ";
cin >> n;
cout << "Input a matrix: " << endl;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> a[i][j];
p = &a[0][0];
transpose(p, n);
cout << "Now, the matrix is: " << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout << setw(4) << a[i][j];
}
cout << endl;
}
return 0;
}
void transpose(int* p, int n)
{
for (int i = 0; i < n; i++)
{
for (int j = i; j < n; j++)
{
int temp = *(p + i * n + j);
*(p + i * n + j) = *(p + j * n + i);
*(p + j * n + i) = temp;
}
}
}
答案 0 :(得分:2)
你应该致电:
transpose(p, M);
而不是:
transpose(p, n);
虽然您的矩阵是3x3
,但您为20x20
矩阵保留了内存。因此,下一行距离20
int
s(两行偏移之间的内存间隙称为 stride )。
为了加快这个过程,您可以实现一个三参数变体:
void transpose(int* p, int m, int n) {
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
int temp = *(p + i * m + j);
*(p + i * m + j) = *(p + j * m + i);
*(p + j * m + i) = temp;
}
}
}
并致电:
transpose(p, M, n);
但说实话,我认为你可以改进你在内存中定义矩阵的方式以及转置算法。您的transpose
方法实际上不是缓存友好型。为了快速计算,我会建议LAPACK包。这些算法以块方式工作,以显着减少缓存故障的数量,并利用多线程来提高性能。有关如何有效转置矩阵的详细信息,请参阅this lecture。