使用 c++ 转置矩阵

Transposing a matrix using c++

本文关键字:转置 c++ 使用      更新时间:2023-10-16

我想编写一个程序来转置 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;
        }
    }
}

你应该调用:

transpose(p, M);

而不是:

transpose(p, n);

尽管您的矩阵是3x3的,但您为20x20矩阵保留了内存。因此,下一行距离该行20 int(两行偏移量之间的内存间隙称为步幅)。

为了加快该过程,您可以实现一个三参数变体:

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包。此类算法逐块工作,以显着减少缓存错误的数量,并利用多线程来提高性能。有关如何有效地转置矩阵的更多详细信息,请参阅此讲座。