第 2 章 第 7 题 矩阵的转置问题 排序法实现

问题分析

  输入:磁带中的 4000 x 4000 矩阵

  输出:转置后的矩阵

  约束:无

解答思路

  常见的思路是遍历上/下三角矩阵,交换 a[i][j] 和 a[j][i] 进行转置。但由于 a[i][j] 和 a[j][i] 在磁带中不是存放在一起的,因此交换这两个元素会很容易引发磁盘IO中断

  因此,对于处理磁盘中的数据,最好是连续的进行处理。( 事实上对内存中的数据也是如此 这样可以充分利用内存预读技术 )

  故可采用以下思路对磁盘中的矩阵进行转置:

    1. 给矩阵文件中的每个元素附加上其行号和列号

    2. 对矩阵以行为关键字进行排序 形成矩阵

    3. 对矩阵以列为关键字进行排序 转置矩阵

  为了测试方便,下面的测试矩阵是存放在内存的二维数组中的。对于存放在磁盘中的情况类似。

代码实现

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 // 声明矩阵元素类型
 6 class Elem {
 7 public:
 8     Elem() {
 9         this->r = 0;
10         this->c = 0;
11         this->e = 0;
12     }
13     int getR() {
14         return r;
15     }
16     int getC() {
17         return c;
18     }
19     int getElem() {
20         return e;
21     }
22     void setElem(int r, int c, int e) {
23         this->r = r;
24         this->c = c;
25         this->e = e;
26     }
27 private:
28     int r;
29     int c;
30     int e;
31 };
32 
33 int main(void) {
34     // 创建二维矩阵并初始化 然后打印 然后输出
35     Elem A[10][10];
36 
37     int t=1;
38     for (int i=0; i<10; i++) {
39         for (int j=0; j<10; j++) {
40             A[i][j].setElem(i, j, t++);
41         }
42     }
43 
44     cout << "矩阵转置前:" << endl;
45     for (int i=0; i<10; i++) {
46         for (int j=0; j<10; j++) {
47             cout << A[i][j].getElem() << " ";
48         }
49         cout << endl;
50     }
51     cout << endl;
52 
53     // 将矩阵按列转置
54     Elem *p = &A[0][0]; 
55     for (int i=1; i<100; i++) {
56         int temr = (p+i)->getR();
57         int temc = (p+i)->getC();
58         int teme = (p+i)->getElem();
59 
60         int j;
61         for (j=i-1; j>=0; j--) {
62             if((p+j)->getC() > temc) { 
63                 (p+j+1)->setElem((p+j)->getR(), (p+j)->getC(), (p+j)->getElem());
64             }
65             else
66                 break;
67         }
68         (p+j+1)->setElem(temr, temc, teme);
69     }
70 
71     cout << "矩阵转置后:" << endl;
72     for (int i=0; i<10; i++) {
73         for (int j=0; j<10; j++) {
74             cout << A[i][j].getElem() << " ";
75         }
76         cout << endl;
77     }
78     cout << endl;
79     
80     return 0;
81 }

运行测试

  

小结

  也许读者会疑惑为何只进行了列排序而没进行行排序。这是因为测试是直接在二维数组中进行的,而二维数组本身自动进行过行排序了。

 

 

posted on 2014-04-02 15:54  空山悟  阅读(288)  评论(0编辑  收藏  举报

导航