您好,登錄后才能下訂單哦!
稀疏矩陣:矩陣中大多數元素為0的矩陣(本文以行序為主序)
稀疏矩陣的三元組表述法:
類型結構:
template <typename T> struct Triple { int _row; int _col; T _value; }; template <typename T> class SparseMatrix { public: SparseMatrix<T>::SparseMatrix(); SparseMatrix(const T* array, size_t row, size_t col, const T& invalid); ~SparseMatrix(); void Display()const; SparseMatrix<T> Transport()const; SparseMatrix<T> FastTransport()const; protected: vector<Triple<T>> _array; size_t _rowCount; size_t _colCount; T _invalid; };
代碼實現壓縮存儲:
//稀疏矩陣 template <typename T> SparseMatrix<T>::SparseMatrix(){} template <typename T> SparseMatrix<T>::SparseMatrix(const T* array, size_t row, size_t col, const T& invalid) :_rowCount(row), _colCount(col), _invalid(invalid) { assert(array); for (size_t i = 0; i < row; ++i) { for (size_t j = 0; j < col; ++j) { if (array[i*col + j] != invalid) { this->_array.push_back({ i, j, array[i*col + j] }); } } } } template <typename T> SparseMatrix<T>::~SparseMatrix() {} template <typename T> void SparseMatrix<T>::Display()const { size_t size = this->_array.size(); size_t iCount = 0; for (size_t i = 0; i < this->_rowCount; ++i) { for (size_t j = 0; j < this->_colCount; ++j) { if (iCount < size && i == this->_array[iCount]._row && j == this->_array[iCount]._col) { cout << this->_array[iCount]._value << " "; ++iCount; } else { cout << this->_invalid << " "; } } cout << endl; } }
稀疏矩陣的轉置:
1)列序遞增轉置法:找出第i行全部元素:從頭到尾掃描三元組表A,找出其中所有_col==i的三元組,轉置后放入三元組表B中。代碼實現如下:
template <typename T> SparseMatrix<T> SparseMatrix<T>::Transport()const { SparseMatrix<T> ret; ret._rowCount = this->_colCount; ret._colCount = this->_rowCount; ret._invalid = this->_invalid; size_t size = this->_array.size(); for (size_t col = 0; col < this->_colCount; ++col) { for (size_t iCount = 0; iCount < size; ++iCount) { if (this->_array[iCount]._col == col) { ret._array.push_back({ this->_array[iCount]._col, this->_array[iCount]._row, this->_array[iCount]._value }); } } } return ret; }
2)一次定位快速轉置法
在方法1中為了使轉置后矩陣的三元組表B仍按行序遞增存放,必須多次掃描被轉置的矩陣的三元組表A。為了能將被轉置三元組表A的元素一次定位到三元組B的正確位置上,需要預先計算以下數據:
i)待轉置矩陣三元組表A每一列中非0元素的總個數,即轉置后矩陣三元組元素B的每一行的非0元素總個數
ii)待轉置矩陣每一列中第一個非0元素在三元組表B中的正確位置,即轉置后矩陣每一行中第一個非0元素在三元組B中的正確位置
為此,需要設兩個數組分別為num[] 和 pos[] ,其中num[col]用來存放三元組表A第col列中非0元素元素總個數,pos[col]用來存放轉置前三元組表A中第col列中第一個非0元素在三元組表B中的存儲位置。
num[col]的計算方法:將三元組表A掃描一遍,對于其中列號為col的元素,給相應的num數組中下標為col的元素加1.
pos[col]的計算方法:
i)pos[0] = 0,表示三元組表A中,列值為0的第一個非0元素在三元組表B中的下標值。
ii)pos[col] = pos[col - 1] + num[col - 1],其中1<=col<A.size();
eg:
0 1 9 0 0 0 0
0 0 0 0 0 0 0
3 0 0 0 0 4 0
0 0 2 0 0 0 0
0 8 0 0 0 0 0
5 0 0 7 0 0 0
col | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
num[col] | 2 | 2 | 2 | 1 | 0 | 1 | 0 |
pos[col] | 0 | 2 | 4 | 6 | 7 | 7 | 8 |
代碼實現:
template <typename T> SparseMatrix<T> SparseMatrix<T>::Transport()const { SparseMatrix<T> ret; ret._rowCount = this->_colCount; ret._colCount = this->_rowCount; ret._invalid = this->_invalid; size_t size = this->_array.size(); for (size_t col = 0; col < this->_colCount; ++col) { for (size_t iCount = 0; iCount < size; ++iCount) { if (this->_array[iCount]._col == col) { ret._array.push_back({ this->_array[iCount]._col, this->_array[iCount]._row, this->_array[iCount]._value }); } } } return ret; } template <typename T> SparseMatrix<T> SparseMatrix<T>::FastTransport()const { SparseMatrix<T> ret; ret._rowCount = this->_colCount; ret._colCount = this->_rowCount; ret._invalid = this->_invalid; size_t size = this->_array.size(); ret._array.resize(size); vector<int> num(this->_colCount); vector<int> pos(this->_colCount); //pos[i] = pos[i-1]+num[i-1] i>0 for (size_t i = 0; i < size; ++i) { ++num[this->_array[i]._col]; } for (size_t col = 1; col < this->_colCount; ++col) { pos[col] = pos[col - 1] + num[col - 1]; } for (size_t i = 0; i < size; ++i) { ret._array[pos[this->_array[i]._col]++] = { this->_array[i]._col, this->_array[i]._row, this->_array[i]._value }; } return ret; }
運行結果:
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。