#include <iostream>
using namespace std;
const int DefaultSize = 100;
typedef int dt;
struct Trituple {//三元组
int row, col;
dt value;
/*Trituple& operator=(Trituple& x) {
row = x.row, col = x.col, value = x.value;
}*/
};
class SparseMatrix {
public:
friend ostream& operator << (ostream& out, SparseMatrix& x);
friend istream& operator >> (istream& in, SparseMatrix& x);
SparseMatrix(int maxSize = DefaultSize);
SparseMatrix(SparseMatrix& x);
~SparseMatrix() { delete[]smArray; }
SparseMatrix Transpose();
SparseMatrix FastTranspose();
SparseMatrix& operator=(SparseMatrix& x);
SparseMatrix Add(SparseMatrix& x);
SparseMatrix Multiply(SparseMatrix& x);
private:
int Rows, Cols, Terms;
Trituple* smArray;
int maxTerms;
};
SparseMatrix::SparseMatrix(int maxSize):maxTerms(maxSize) {
if (maxSize < 1) {
cerr << "初始化错误" << endl; exit(1);
}
smArray = new Trituple[maxSize];
if(smArray==NULL) {
cerr << "存储分配错误" << endl; exit(1);
}
Rows = Cols = Terms = 0;
}
SparseMatrix::SparseMatrix(SparseMatrix& x) {
Rows = x.Rows; Cols = x.Cols; Terms = x.Terms; maxTerms = x.maxTerms;
smArray = new Trituple[maxTerms];
if (smArray == NULL) {
cerr << "存储分配错误" << endl; exit(1);
}
for (int i = 0; i < Terms; i++)smArray[i] = x.smArray[i];
}
SparseMatrix SparseMatrix::Transpose() {
SparseMatrix b(maxTerms);
b.Rows = Cols;
b.Cols = Rows;
b.Terms = Terms;
if (Terms) {
int k, i, currenntB = 0;
for(k=0;k<Cols;k++)
for (i = 0; i < Terms; i++)
if (smArray[i].col = k) {
b.smArray[currenntB].row = k;
b.smArray[currenntB].col = smArray[i].row;
b.smArray[currenntB++].value = smArray[i].value;
}
}
return b;
}
SparseMatrix SparseMatrix::FastTranspose() {
//对稀疏矩阵( * this 指示)做快速转置,结果放在b中并通过函数返回
int* rowSize = new int[Cols];//辅助数组,统计各列非零元素个数
int* rowStart = new int[Cols];//辅助数组,预计转置后各行存放位置
SparseMatrix b(maxTerms); // 1存放转置结果
b.Rows = Cols;
b.Cols = Rows;
b.Terms = Terms;
if (Terms > 0) {
int i, j;
for (i = 0; i < Cols; i++) rowSize[i] = 0;
for (i = 0; i < Terms; i++) rowSize[smArray[i].col]++;
rowStart[0] = 0;
for (i = 1; i < Cols; i++)
rowStart[i] = rowStart[i - 1] + rowSize[i - 1];
for (i = 0; i < Terms; i++) {//从a向b传送
j = rowStart[smArray[i].col]; //第1个非零元素在b中应放位置
b.smArray[j].row = smArray[i].col;
b.smArray[j].col = smArray[i].row;
b.smArray[j].value = smArray[i].value;
rowStart[smArray[i].col] ++;
}
}
delete[] rowSize; delete[]rowStart;
return b;
}
SparseMatrix& SparseMatrix::operator=(SparseMatrix& x) {
Rows = x.Rows; Cols = x.Cols; Terms = x.Terms; maxTerms = x.maxTerms;
smArray = new Trituple[maxTerms];
if (smArray == NULL) {
cerr << "存储分配错误" << endl; exit(1);
}
for (int i = 0; i < Terms; i++)smArray[i] = x.smArray[i];
}
SparseMatrix SparseMatrix::Add(SparseMatrix& b) {
//两个稀疏矩阵A ( * this指示)与B (参数表中的b)相加,结果在Result中
SparseMatrix result;
result.Rows = Rows;
result.Cols = Cols;
//结果矩阵的三元组表
if (Rows != b.Rows || Cols != b.Cols) {
cout << "Incompatible matrices" << endl; //两个 矩阵规格不一样
return result;//返回空矩阵
}
int i = 0, j = 0, index_a, index_b;
result.Terms = 0;
while (i < Terms && j < b.Terms) {
index_a = Cols * smArray[i].row + smArray[i].col;
index_b = Cols * b.smArray[j].row + b.smArray[j].col;
if (index_a < index_b) {
result.smArray[result.Terms] = smArray[i];
i++;
}
else if (index_a > index_b) {
result.smArray[result.Terms] = b.smArray[j];
j++;
}
else {
result.smArray[result.Terms] = smArray[i];
result.smArray[result.Terms].value = smArray[i].value + b.smArray[j].value;
i++, j++;
}
result.Terms++;
}
//复制剩余元素。
for (; i < Terms; i++) {
result.smArray[result.Terms] = smArray[i]; result.Terms++;
}
for (; j < b.Terms; j++) {
result.smArray[result.Terms] = b.smArray[i]; result.Terms++;
}
return result;
}
SparseMatrix SparseMatrix::Multiply(SparseMatrix& b) {
//两个稀疏矩阵A ( * this指示)与B (参数表中的b)相加,结果在Result中
SparseMatrix result;
result.Rows = Rows;
result.Cols = b.Cols;
//结果矩阵的三元组表
if (Cols != b.Rows) {
cerr << "Incompatible matrices" << endl;//A列数与B行数不等
return result;// 返回空矩阵
}
if (Terms == maxTerms || b.Terms == maxTerms) {
cerr << "One additional space inaor b needed" << endl;
return result;
//空间不足,返回空矩阵
}
int* rowSize = new int[b.Rows];//矩阵 B各行非零元素个数
int* rowStart = new int[b.Rows + 1];//矩阵B各行在三元组开始位置
dt* temp = new dt[b.Cols];
//暂存每一行计算结果
int i, Current, lastInResult, RowA, ColA, ColB;
for (i = 0; i < b.Rows; i++) rowSize[i] = 0;
for (i = 0; i < b.Terms; i++) rowSize[b.smArray[i].row]++;
rowStart[0] = 0;
//B第i行非零元素开始位置
for (i = 1; i <= b.Rows; i++)
rowStart[i] = rowStart[i - 1] + rowSize[i - 1];
Current = 0; lastInResult = -1;//a扫描指针及result存指针
while (Current < Terms) { //生成result的当前行temp
RowA = smArray[Current].row; //当前行的行号
for (i = 0; i < b.Cols; i++) temp[i] = 0;
while (Current < Terms && smArray[Current].row == RowA) {
ColA = smArray[Current].col; //矩阵 A当前扫描到元素的列号
for (i = rowStart[ColA]; i < rowStart[ColA + 1]; i++) {
ColB = b.smArray[i].col; //矩阵B中相乘元素的列号
temp[ColB] += smArray[Current].value * b.smArray[i].value;
}
}//A的RowA行与B的ColB列相乘
Current++;
}
for (i = 0; i < b.Cols; i++)
if (temp[i] != 0) {//将temp中的非零元素压缩到result中去
lastInResult++;
result.smArray[lastInResult].row = RowA;
result.smArray[lastInResult].col = i;
result.smArray[lastInResult].value = temp[i];
}
result.Rows = Rows; result.Cols = b.Cols;
result.Terms = lastInResult + 1;
delete[]rowSize, delete[]rowStart, delete[]temp;
return result;
}
ostream& operator<<(ostream& out, SparseMatrix& x) {
out << "rows= " << x.Rows
<< " cols= " << x.Cols
<< " Terms= " << x.Terms << endl;
for (int i = 0; i < x.Terms; i++)
out << "M[" << x.smArray[i].row << "][" << x.smArray[i].col
<< "]= " << x.smArray[i].value << endl;
return out;
}
istream& operator>>(istream& in, SparseMatrix& x) {
cout << "输入行列和不为零的数字个数" << endl;
in >> x.Rows >> x.Cols >> x.Terms;
if (x.Terms > x.maxTerms) {
cerr << "输入大小错误" << endl; exit(1);
}
for (int i = 0; i < x.Terms; i++) {
cout << "输入行列和该位置数字" << endl;
in >> x.smArray[i].row >> x.smArray[i].col >> x.smArray[i].value;
}
return in;
}
int main(){
SparseMatrix sq1,sq2,sq3;
cin >> sq1>>sq2;
cout << sq1<<sq2<<endl;
sq3=sq1.Add(sq2);
cout <<sq3<< sq1 << sq2 << endl;
sq2.FastTranspose();
cout << sq2 << endl;
sq3 = sq1.Multiply(sq2);
cout <<sq3<< sq1 << sq2 << endl;
}
数据结构——三元组实现稀松矩阵
最新推荐文章于 2021-04-18 14:54:10 发布