(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] << "\n"; 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 }