问题描述:
7. 在20世纪60年代早期,Vic Vyssotsky与一个程序员一起工作,该程序员需要转置一个存储在磁带上的4000x4000的矩阵(每条记录的格式相同,为数十个字节)。
他的同事最初提出的程序需要运行50个小时。Vyssotsky如何将运行时间减少到半个小时呢?
问题解析:
1、首先应该知道什么是转置矩阵?
2、这里的“每条记录”说的是的矩阵里的每一个数。
解决方案:
解决方案1:
作者给出的解答是:为每条记录插入列号和行号,然后调用系统的磁带排序程序先按列排序再按行排序,最后使用另一个程序删除列号和行号。
我这里依照这个思路,实现了一个类似的代码,当然这里仅仅是演示原理而已!代码如下:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
#include <cstdio>
#include <cstdlib> // qsort #include <cstring> // strlen #include <cassert> // assert #define MATRIXLEN 8 // 矩阵长度 #define error( str ) fatal_error( str ) #define fatal_error( str ) fprintf( stderr, "%s\n", str ), exit( 1 ) typedef struct { int row; // 行号 int column; // 列号 int value; // 值 } Data; Data matrix[MATRIXLEN* 2] = { 0}; int datacomp1( const void* a, const void* b) { return ((Data*)a)->row - ((Data*)b)->row; } int datacomp2( const void* a, const void* b) { return ((Data*)a)->column - ((Data*)b)->column ; } int main() { FILE* rfile = fopen( "matrix.txt", "r"); if ( NULL == rfile){ fatal_error( "不能打开matrix.txt文件!\n"); } printf( "请输入一个矩阵:\n"); // 从文件中读取数据 Data data; int index = 0, cur_row = 0, cur_column = 0; while(fscanf(rfile, "%d", &data.value) != EOF){ if (index != 0 && index % 4 == 0){ cur_row++; cur_column = 0; } data.row = cur_row; data.column = cur_column++; matrix[index++] = data; } // 列排序 qsort(matrix, MATRIXLEN * 2, sizeof(Data), datacomp2); // 行排序(列相等情况下) for ( int i = 0; i < MATRIXLEN* 2; i += 4){ qsort(&matrix[i], 4, sizeof(Data), datacomp1); } printf( "该矩阵的转置矩阵是:\n"); // 打印 for ( int i = 0; i < MATRIXLEN* 2; i++){ if (i != 0 && i % 4 == 0) { printf( "\n"); } printf( "%d\t", matrix[i].value); } return 0; } |
输出结果如下:
心得疑惑:
1、通过此题又重新复习了转置矩阵的概念,加深了对qsort的认识。
2、转置矩阵有哪些用处呢?