稀疏矩阵的转置
稀疏矩阵:M*N的矩阵,矩阵中有效值的个数远小于无效值的个数,且这些数据的分布没有规律
创新互联建站专业为企业提供福海网站建设、福海做网站、福海网站设计、福海网站制作等企业网站建设、网页设计与制作、福海企业网站模板建站服务,10年福海做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
如下图所示:
一般情况下,我们会想到只要交换对应的行和列,但是这种做法很浪费时间和空间,所以我们可以利用三元组进行存储,压缩存储极少数的有效数据,使用{row,col,value}三元组存储每一个有效数据,三元组按原矩阵中的位置,以行优先级先后顺序依次存放。
#define _CRT_SECURE_NO_WARNINGS 1 #pragma once #include#include using namespace std; template struct Triple //定义三元组 { int _row; int _col; T _value; Triple(int row, int col, T& value) :_row(row) , _col(col) , _value(value) {} Triple() :_row(0) , _col(0) , _value(0) {} }; template class SparseMatrix { public: SparseMatrix(T* a, int m, int n, const T& invalid)//invalid为非法值 :_rowsize(m) , _colsize(n) , _invaild(invalid) { for (int i = 0; i < m; ++i) { for (int j = 0; j < n; j++) { if (a[i*n + j] != invalid) { Triple tmp(i, j, a[i*n + j]); _a.push_back(tmp); } } } } SparseMatrix(size_t rowsize, size_t colsize, T invaild) :_rowsize(rowsize), _colsize(colsize), _invaild(invaild) {} void display(T* a, int m, int n, const T& invalid) //打印稀疏矩阵 { int p = 0; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; j++) { if (p < _a.size() && _a[p]._row == i&&_a[p]._col == j) { cout << _a[p]._value << " "; p++; } else { cout << invalid << " "; } } cout << endl; } } SparseMatrix Transport() //逆转矩阵 { //务必保持行优先 SparseMatrix sm(_colsize, _rowsize, _invaild); for (size_t i = 0; i < _colsize; i++) { size_t index = 0; while (index < _a.size()) { if (_a[index]._col == i) { Triple mm; mm._col = _a[index]._row; mm._row = _a[index]._col; mm._value = _a[index]._value; sm._a.push_back(mm); } ++index; } } return sm; } SparseMatrix FastTransport() //快速转置 { SparseMatrix temp; temp._a.resize(_a.size()); int* rowcounts = new int[_col]; int* rowstarts = new int[_col]; memset(rowcounts, 0, sizeof((int)*_col)); memset(rowstarts, 0, sizeof((int)*_col)); size_t index = 0; while (index < _a.size()) { rowcounts[_a[index]._col]++; ++index; } rowstarts[0] = 0; for (size_t i = 0; i < _col; ++i) { rowstarts[i] = rowstarts[i - 1] + rowcounts[i - 1]; } while (index < _a.size()) { size_t& begin = rowstarts[_a[index]._col]; Triple tp; tp._row = _a[index]._col; tp._col = _a[index]._row; tp._value = _a[index]._value; tmp._a[rowstarts++] = tp; ++index; } delete[] _a; return tmp; } protected: size_t _rowsize; size_t _colsize; T _invaild; vector > _a; }; 测试代码如下: void test() { int a[6][5] = { { 1, 0, 3, 0, 5 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 2, 0, 4, 0, 6 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }; SparseMatrix d((int*)a, 6, 5, 0); SparseMatrix tmp = d.Transport(); cout << "转置之前:" << endl; d.display((int*)a, 6, 5, 0); cout << endl; cout << "转置之后:" << endl; tmp.display((int*)a, 5, 6, 0); } int main() { test(); system("pause"); return 0; }
运行结果如下:
分享文章:稀疏矩阵的转置
网址分享:http://azwzsj.com/article/jiojeo.html