#include <iostream>
using namespace std;
const int DefaultSize = 100;
typedef int dt;
struct Trituple {
int row, col;
dt 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() {
int* rowSize = new int[Cols];
int* rowStart = new int[Cols];
SparseMatrix b(maxTerms);
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++) {
j = rowStart[smArray[i].col];
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) {
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) {
SparseMatrix result;
result.Rows = Rows;
result.Cols = b.Cols;
if (Cols != b.Rows) {
cerr << "Incompatible matrices" << endl;
return result;
}
if (Terms == maxTerms || b.Terms == maxTerms) {
cerr << "One additional space inaor b needed" << endl;
return result;
}
int* rowSize = new int[b.Rows];
int* rowStart = new int[b.Rows + 1];
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;
for (i = 1; i <= b.Rows; i++)
rowStart[i] = rowStart[i - 1] + rowSize[i - 1];
Current = 0; lastInResult = -1;
while (Current < Terms) {
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;
for (i = rowStart[ColA]; i < rowStart[ColA + 1]; i++) {
ColB = b.smArray[i].col;
temp[ColB] += smArray[Current].value * b.smArray[i].value;
}
}
Current++;
}
for (i = 0; i < b.Cols; i++)
if (temp[i] != 0) {
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;
}