p55_59.cpp
上传用户:chaiyuqiu
上传日期:2022-08-03
资源大小:27k
文件大小:7k
源码类别:

数据结构

开发平台:

C/C++

  1. //Test is T55_59.cpp
  2. #include <iostream.h>
  3. const int MaxTerms = 100;
  4. template <class Type> class SparseMatrix; //稀疏矩阵的类声明
  5. template <class Type> class Trituple { //三元组类Trituple
  6. friend class SparseMatrix<Type> ;
  7. friend istream & operator >> ( istream & , SparseMatrix<Type> & );
  8. friend ostream & operator << ( ostream & , SparseMatrix<Type> & );
  9. private:
  10.    int row, col; //非零元素的行号、列号
  11.    Type value; //非零元素的值
  12. };
  13. template <class Type> class SparseMatrix {
  14. //对象: 是一个三元组<row, column, value>的集合。其中, row和column是整数, 记忆矩阵
  15. //元素所在的行号和列号,而value是矩阵元素的值。
  16. friend istream & operator >> ( istream & , SparseMatrix<Type> & );
  17. friend ostream & operator << ( ostream & , SparseMatrix<Type> & );
  18. public:
  19.    SparseMatrix ();
  20.    SparseMatrix ( int MaxRow, int MaxCol ): Rows( MaxRow ), Cols( MaxCol ){};    //构造函数
  21. //建立一个MaxRow行, Maxcol列的稀疏矩阵。
  22.    SparseMatrix<Type> Transpose ( );
  23. //对*this指示的三元组数组中各个三元组交换其行、列的值, 得到其转置矩阵。
  24.    SparseMatrix<Type> Add ( SparseMatrix<Type> b );
  25. //当矩阵a(*this指示)与矩阵b的行、列数相同时, 将这两个矩阵的对应项相加。
  26.    SparseMatrix<Type> Multiply ( SparseMatrix<Type> b );
  27. //按公式 c[i][j]=∑(a[i][k]*b[k][j]) 实现矩阵a与b相乘。k=0, 1, …, a的列数-1。
  28.    SparseMatrix<Type> FastTranspose ( );
  29.    SparseMatrix<Type> EmptyMatrix ( );
  30. private:
  31.    int Rows, Cols, Terms ;
  32.    Trituple<Type> smArray[MaxTerms];
  33. };
  34. template <class Type> SparseMatrix<Type> SparseMatrix<Type>::Transpose ( ) {
  35. //将稀疏矩阵a(*this指示)转置, 结果在稀疏矩阵b中。
  36.    SparseMatrix<Type> b ( Cols, Rows ); //创建一个稀疏矩阵类的对象b
  37.    b.Rows = Cols; //矩阵b的行数=矩阵a的列数
  38.    b.Cols = Rows; //矩阵b的列数=矩阵a的行数
  39.    b.Terms = Terms; //矩阵b的非零元素数=矩阵a的非零元素数
  40.    if ( Terms > 0 ) { //非零元素个数不为零
  41.       int CurrentB = 0; //存放位置指针
  42.       for ( int k=0; k<Cols; k++ ) //按列号做扫描,做Cols趟
  43.    for ( int i=0; i<Terms; i++ )  //在数组中找列号为k的三元组
  44.   if ( smArray[i].col == k ) { //第i个三元组中元素的列号为k
  45. b.smArray[CurrentB].row = k; //新三元组的行号
  46. b.smArray[CurrentB].col = smArray[i].row; //新三元组的列号
  47. b.smArray[CurrentB].value = smArray[i].value; //新三元组的值
  48. CurrentB++; //存放指针进1
  49.   }
  50.    }
  51.    return b;
  52. }
  53. template <class Type> SparseMatrix<Type> SparseMatrix<Type>::FastTranspose ( ) {
  54. //对稀疏矩阵a(*this指示)做快速转置, 结果放在b中, 时间代价为O(Terms+Columns)
  55.    int *rowSize = new int[Cols]; //辅助数组, 统计各列非零元素个数
  56.    int *rowStart = new int[Cols]; //辅助数组, 预计转置后各行存放位置
  57.    SparseMatrix<Type> b ( Cols, Rows );  //存放转置结果
  58.    b.Rows = Cols;  b.Cols = Rows;  b.Terms = Terms;
  59.    if ( Terms > 0 ) {
  60.  for ( int i=0; i<Cols; i++ ) rowSize[i] = 0;  //统计矩阵b中第i行非零元素个数
  61.  for ( i=0; i<Terms; i++ ) rowSize[smArray[i].col]++;
  62.       //根据矩阵a中第i个非零元素的列号, 将rowSize相当该列的计数加1
  63.  rowStart[0] = 0; //计算矩阵b第i行非零元素的开始存放位置
  64.  for ( i=1; i <Cols; i++ ) //rowStart[i] = 矩阵b的第i行的开始存放位置
  65.    rowStart[i] = rowStart[i-1]+rowSize[i-1];
  66.  for ( i=0; i<Terms; i++ ) { //从a向b传送
  67.    int j = rowStart[smArray[i].col]; // j为第i个非零元素在b中应存放的位置
  68.    b.smArray[j].row = smArray[i].col;
  69.    b.smArray[j].col = smArray[i].row;
  70.    b.smArray[j].value = smArray[i].value;
  71.    rowStart[smArray[i].col]++; //矩阵b第i行非零元素的存放位置加一
  72.  }
  73.    }
  74.    delete [ ] rowSize;   delete [ ] rowStart;
  75.    return b;
  76. }
  77. template <class Type> SparseMatrix<Type> SparseMatrix<Type>::Multiply(SparseMatrix<Type> b)
  78. //两个稀疏矩阵A (*this指示) 与B (参数表中的b) 相乘, 结果在Result中
  79. {
  80.     if ( Cols != b.Rows ) {
  81.  cout << "Incompatible matrices" << endl; //A矩阵列数与B矩阵行数不等
  82.  return EmptyMatrix ( ); //不能做乘法的矩阵,返回空矩阵
  83.     }
  84.     if ( Terms == MaxTerms || b.Terms == MaxTerms ) { //有一个矩阵的项数达到最大
  85.        cout << "One additional space in a or b needed" << endl;
  86.  return EmptyMatrix ( ); //空间不足,返回空矩阵
  87.     }
  88.     int *rowSize = new int[b.Rows];   //辅助数组, 矩阵B各行非零元素个数
  89.     int *rowStart = new int[b.Rows+1];  //辅助数组, 矩阵B各行在三元组开始位置
  90.     Type * temp = new Type[b.Cols]; //临时数组, 暂存每一行计算结果
  91.     SparseMatrix<Type> result ( Rows, b.Cols ); //结果矩阵的三元组表result
  92.     for ( int i=0; i<b.Cols; i++ ) rowSize[i] = 0;  //统计矩阵B中第i行非零元素个数
  93.     for ( i=0; i<b.Terms; i++ ) rowSize[smArray[i].row]++;
  94.     rowStart[0] = 0; //计算矩阵B第i行非零元素的开始位置
  95.     for ( i=1; i <=b.Cols; i++ ) rowStart[i] = rowStart[i-1] + rowSize[i-1];
  96.     int Current = 0,  lastInResult = -1; //a.smArray扫描指针及result存放指针
  97.     while ( Current < Terms ) { //生成result的当前行temp
  98.   int RowA = smArray[Current].row; //当前行的行号
  99.   for ( i=0; i<b.Cols; i++ ) temp[i] = 0; //temp初始化
  100.   while ( Current < Terms && smArray[Current].row == RowA ) {
  101.      int ColA = smArray[Current].col; //矩阵A当前扫描到元素的列号
  102.      for ( i=rowStart[ColA]; i<rowStart[ColA+1]; i++ ) {
  103.   int ColB = b.smArray[i].col; //矩阵B中相乘元素的列号
  104.   temp[ColB] = temp[ColB] + smArray[Current].value * b.smArray[i].value;
  105.      } //A的RowA行与B的ColB列相乘
  106.     Current++;
  107.   }
  108.   for ( i=0; i<b.Cols; i++ )
  109.     if ( temp[i] != 0 ) { //将temp中的非零元素压缩到result中去
  110.  lastInResult++;
  111.  result.smArray[lastInResult].row = RowA;
  112.  result.smArray[lastInResult].col = i;
  113.  result.smArray[lastInResult].value = temp[i];
  114.     }
  115.     }
  116.     result.Rows = Rows;  result.Cols = b.Cols;  result.Terms = lastInResult+1;
  117.     delete [ ] rowSize;  delete [ ] rowStart;  delete [ ] temp;
  118.     return result;
  119. }
  120. template <class Type>  SparseMatrix<Type> SparseMatrix<Type>:: EmptyMatrix ( ) {
  121.     SparseMatrix<Type> b(0,0);
  122.     return b;
  123. }
  124. template <class Type> istream & operator >> ( istream & is , SparseMatrix<Type> & matrix) {
  125.     cout << "Rows and Cols: " << endl;
  126.     is >> matrix.Rows >> matrix.Cols;
  127.     cout << "row col value : ( ended by row = -1 ) " << endl;
  128.     matrix.Terms = -1 ;
  129.     do {
  130. matrix.Terms ++;
  131. is >> matrix.smArray[matrix.Terms].row
  132.    >> matrix.smArray[matrix.Terms].col
  133.    >> matrix.smArray[matrix.Terms].value;
  134.     } while ( matrix.smArray[matrix.Terms].row != -1 );
  135.     return is;
  136. }
  137. template <class Type> ostream & operator << ( ostream & os , SparseMatrix<Type> & matrix) {
  138.     if ( matrix.Terms == 0 ) { os << "It is empty."; return os}
  139.     os << "Rows: " << matrix.Rows << endl;
  140.     os << "Cols: " << matrix.Cols << endl;
  141.     os << "col row value: " << endl;
  142.     for (int i=0; i<matrix.Terms; i++) {
  143. os << matrix.smArray[i].row << " "
  144.    << matrix.smArray[i].col << " "
  145.    << matrix.smArray[i].value << endl;
  146.     }
  147.     return os;
  148. }