(2019年2月19日注:这篇文章原先发在自己github那边的博客,时间是2017年2月5日)
对于任意非n阶矩阵的转置,用c++应该怎么写代码,思考了一下,发现并没有那么简单,上网找到了一个比较好的算法,叫做矩阵原地转置矩阵算法。基于别人的代码,改写成可以使用指针动态分配内存的方法。
先放传送门:C++实现矩阵原地转置算法的实现
原理并不难,那篇文章非常的详细,我不再赘述,下面把改写好的代码发出来。
1 /************************************************************************* 2 > File Name: matrix_transpose.cpp 3 > Author: SongLee 4 > Modified: JCChan 5 ************************************************************************/ 6 #include<iostream> 7 using namespace std; 8 /* 后继 */ 9 int getNext(int i, int m, int n) 10 { 11 return (i%n)*m + i / n; 12 } 13 /* 前驱 */ 14 int getPre(int i, int m, int n) 15 { 16 return (i%m)*n + i / m; 17 } 18 /* 处理以下标i为起点的环 */ 19 void movedata(int *mtx, int i, int m, int n) 20 { 21 int temp = mtx[i]; // 暂存 22 int cur = i; // 当前下标 23 int pre = getPre(cur, m, n); 24 // 从最后一个数开始,获得它的前驱,直到前驱的值和最后一位值相等,相当于交换的逆过程 25 while (pre != i) 26 { 27 mtx[cur] = mtx[pre]; 28 cur = pre; 29 pre = getPre(cur, m, n); 30 } 31 mtx[cur] = temp; 32 } 33 /* 转置,即循环处理所有环 */ 34 void transpose(int *mtx, int m, int n) 35 { 36 for (int i = 0; i<m*n; ++i) 37 { 38 int next = getNext(i, m, n); 39 while (next > i) // 若存在后继小于i说明重复 40 next = getNext(next, m, n); 41 if (next == i) // 处理当前环 42 movedata(mtx, i, m, n); 43 } 44 } 45 void input(int *mtx, int row, int column) { 46 for (int i = 0; i < row; i++) { 47 for (int j = 0; j < column; j++) { 48 cout << "请输入矩阵的第" << i + 1 << "行第" << j + 1 << "个元素:"; 49 // 根据矩阵的坐标推算它在一维数组中的位置。 50 cin >> *(mtx + column*i + j); 51 } 52 } 53 } 54 /* 输出矩阵 */ 55 void print(int *mtx, int m, int n) 56 { 57 for (int i = 0; i<m*n; ++i) 58 { 59 if ((i + 1) % n == 0) 60 cout << mtx[i] << " "; 61 else 62 cout << mtx[i] << " "; 63 } 64 } 65 /* 测试 */ 66 int main() 67 { 68 int row, column; 69 cout << "请输入矩阵的行数:"; 70 cin >> row; 71 cout << "请输入矩阵的列数:"; 72 cin >> column; 73 int *matrix = new int[row*column]; 74 input(matrix, row, column); 75 cout << "Before matrix transposition:" << endl; 76 print(matrix, row, column); 77 transpose(matrix, row, column); 78 cout << "After matrix transposition:" << endl; 79 print(matrix, column, row); 80 delete[] matrix; 81 system("pause"); 82 return 0; 83 }
结果如下
对于n阶方阵来说,情况则简单的多,同样放上代码。
1 #include<iostream> 2 using namespace std; 3 void move(int *matrix, int n) 4 { 5 int i, j, k; 6 for (i = 0; i<n; i++) 7 for (j = 0; j<i; j++) 8 { 9 k = *(matrix + i*n + j); 10 *(matrix + i*n + j) = *(matrix + j*n + i); 11 *(matrix + j*n + i) = k; 12 } 13 } 14 int main() 15 { 16 int n, i, j; 17 int *p; 18 cout << "请输入矩阵的维数:"; 19 cin >> n; 20 p = new int[n*n]; 21 cout << "输入矩阵的元素" << endl; 22 for (i = 0; i<n; i++) 23 for (j = 0; j<n; j++) 24 { 25 cout << "第" << i + 1 << "行第" << j + 1 26 << "个元素为:"; 27 cin >> p[i*n + j]; 28 } 29 cout << "输入的矩阵的为:" << endl; 30 for (i = 0; i<n; i++) 31 { 32 for (j = 0; j<n; j++) 33 cout << p[i*n + j] << " "; 34 cout << endl; 35 } 36 move(p, n); 37 cout << "转置后的矩阵的为:" << endl; 38 for (i = 0; i<n; i++) 39 { 40 for (j = 0; j<n; j++) 41 cout << p[i*n + j] << " "; 42 cout << endl; 43 } 44 delete[] p; 45 system("pause"); 46 return 0; 47 }