稀疏矩阵的压缩存储

稀疏矩阵的压缩存储:
实现稀疏矩阵压缩存储,并实现矩阵转置和求和。
输入矩阵时,首先需要输入非零元素的个数,然后分别输入矩阵的 行号,列号和值。
输完2个矩阵后,自动进行计算第一个矩阵的转置以及两个矩阵的和。
例如:输入如下:
100 90 5 //矩阵的行数为100,列数为90,共5个非零元素。
1 10 100 //a(1,10)=100
50 60 200//a(50,60)=200
50 80 100//a(50,80)=100
60 60 200//a(60,60)=200
99 89 10//a(99,89)=10
100 90 2 //矩阵b的行数为100,列数为90,共2个非零元素。
1 1 10 //b(1,1)=10
50 60 -200//b(50,60)=-200 


#include <iostream>
using namespace std;
struct Triple {                         //三元组
	int Row, Col;	                     //非零元素行号/列号
	int value;                 //非零元素的值
	void operator = (Triple & R)      //赋值
	{
		Row = R.Row;  Col = R.Col;  value = R.value;
	}
};
class SparseMatrix {
private:					 //a = a*b
	int Rows, Cols, Terms;                    //行/列/非零元素数
	Triple   *smArray;                           //三元组表
public:
	SparseMatrix(int maxSize=100);               //构造函数
	void Transpose(SparseMatrix& B);                   //转置
	SparseMatrix Add(SparseMatrix& b);  //a = a+b
	friend ostream& operator << (ostream& out, SparseMatrix &M);
	friend istream& operator >> (istream& in, SparseMatrix &M);
};
SparseMatrix::SparseMatrix(int maxSize)
{
	Terms = maxSize;
	smArray = new Triple[maxSize];
	Rows = Cols = 0;
};
void SparseMatrix::Transpose(SparseMatrix & B)
{
	int *rowSize = new int[Cols];       //列元素数数组
	int *rowStart = new int[Cols];      //转置位置数组
	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;
}
SparseMatrix SparseMatrix::Add(SparseMatrix & b)
{
	SparseMatrix res;
	int i = 0, j = 0, index_a, index_b;
	res.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) {
			res.smArray[res.Terms] = smArray[i];
			i++;
		}
		else if (index_a > index_b) {
			res.smArray[res.Terms] = b.smArray[j];
			j++;
		}
		else{
			int vv= smArray[i].value + b.smArray[j].value;
			if (vv != 0) {
				res.smArray[res.Terms] = smArray[i];
				res.smArray[res.Terms].value = vv;
			}
			if (vv == 0) {
				res.Terms--;
			}
			i++; j++;
		}
		res.Terms++;
	}
	for (; i < Terms; i++) {
		res.smArray[res.Terms] = smArray[i];
		res.Terms++;
	}
	for (; j < b.Terms; j++) {
		res.smArray[res.Terms] = b.smArray[j];
		res.Terms++;
	}
	return res;
}


ostream & operator<<(ostream & out, SparseMatrix & M)
{
	for (int i = 0; i < M.Terms; i++) {
		out << M.smArray[i].Row << " " << M.smArray[i].Col << " " << M.smArray[i].value << endl;
	}
	return out;
	// TODO: 在此处插入 return 语句
}

istream & operator>>(istream & in, SparseMatrix & M)
{
	in >> M.Rows >> M.Cols >> M.Terms;
	for (int i = 0; i < M.Terms; i++) {
		in >> M.smArray[i].Row >> M.smArray[i].Col >> M.smArray[i].value;
	}
	return in;
	// TODO: 在此处插入 return 语句
}
int main()
{
	SparseMatrix s,s2,s3,s4;
	cin >> s;
	cin >> s3;
	s.Transpose(s2);
	cout << "The transformed matrix is:" << endl;
	cout << s2;
	s4=s.Add(s3);
	cout << "The added matrix is:" << endl;
	cout << s4;
    return 0;
}

posted @ 2018-05-02 19:27  UnderScrutiny  阅读(647)  评论(0编辑  收藏  举报