稀疏矩阵

本文介绍了一个C++实现的稀疏矩阵类,包括基本的稀疏矩阵加法运算和两种转置方法。该类使用三元组表示非零元素,并提供了手动输入和自动测试输入的功能。此外,还实现了两种不同的转置算法,一种是普通转置,另一种是快速压缩转置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>
#include <cstdio>
#define  ElemType int
class Term
{
public:
	int  x;
	int  y;
	ElemType  v;
	Term()  {}
	Term(int  sx, int  sy, ElemType  sv) :x(sx), y(sy), v(sv) { }
};
class SparseMatrix
{
private:
	int  MaxTerms;
	int  rows, cols;
public:
	Term  *a;
	int  terms;
	SparseMatrix(int r = 0, int c = 0) :rows(r), cols(c)
	{
		MaxTerms = r*c;
		a = new Term[MaxTerms];
		terms = 0;
	}
	~SparseMatrix()	{ delete[]a; }
  
	void Transpose(SparseMatrix &B);   //元素的转置
	void newTranspose(SparseMatrix &B);
	void SInput(int num);         //输入非零元素
	void sort();



	//以友元重载
	template<class T>
	friend std::basic_ostream<T> & operator<<(std::basic_ostream<T>&os, const SparseMatrix &spaMat);
	friend std::istream & operator>>(std::istream &is, SparseMatrix &spaMat);


	//以成员重载
	SparseMatrix & operator+(SparseMatrix &spaMat);
};

template<class T>
inline std::basic_ostream<T> & operator<<(std::basic_ostream<T>&os, const SparseMatrix &spaMat)
{
	for (int i = 0; i < spaMat.terms; ++i)
	{
		os << "第" << spaMat.a[i].x << "行,   第" << spaMat.a[i].y << "列的值是:" << spaMat.a[i].v << std::endl;
	}
	os << "-------------------------------------------------------------\n";

	return os;
}

inline std::istream & operator>>(std::istream &is, SparseMatrix &spaMat)
{
	int tmpX, tmpY, tmpV;
	int index = 0;
	while (scanf_s("%d%d%d", &tmpX, &tmpY, &tmpV) == 3 && tmpX != '#' && tmpY != '#' && tmpV != '#')
	{
		Term tmp(tmpX, tmpY, tmpV);
		spaMat.a[index++] = tmp;
	}
	spaMat.terms = index;
	return is;
}

SparseMatrix & SparseMatrix::operator+(SparseMatrix &c)
{
	for (int i = 0; i < terms; ++i)
	{
		for (int j = 0; j < c.terms; ++j)
		{
			if (a[i].x == c.a[j].x && a[i].y == c.a[j].y && c.a[j].v)
			{
				a[i].v += c.a[j].v;
				c.a[j].v = 0;
				break;
			}

		}
	}

	for (int i = 0; i < c.terms; ++i)
	{
		if (c.a[i].v)
		{

			a[terms] = c.a[i];
			++terms;
		}
	}
	sort();
	return *this;
}
void SparseMatrix::Transpose(SparseMatrix  &B)
{//普通转置
	B.terms = terms; B.rows = cols; B.cols = rows;
	for (int i = 0; i < cols; ++i)
	{
		for (int j = 0; j < terms; ++j)
		{
			if (a[j].y == i)
			{
				B.a[j].x = a[j].y;
				B.a[j].y = a[j].x;
				B.a[j].v = a[j].v;
			}
		}
	}
}


void SparseMatrix::SInput(int num)
{//(测试用)自动输入
	terms = num;
	a[0].x = 0; a[0].y = 1; a[0].v = 12;
	a[1].x = 0; a[1].y = 2; a[1].v = 9;
	a[2].x = 2; a[2].y = 0; a[2].v = -3;
	a[3].x = 2; a[3].y = 4; a[3].v = 14;
	a[4].x = 3; a[4].y = 2; a[4].v = 24;
	a[5].x = 4; a[5].y = 1; a[5].v = 18;
	a[6].x = 5; a[6].y = 0; a[6].v = 15;
	a[7].x = 5; a[7].y = 3; a[7].v = -7;
}

void SparseMatrix::sort()
{//排序
	for (int i = 0; i < terms; ++i)
	{
		int mins = i;
		for (int j = i; j < terms; ++j)
		{
			if (a[mins].x > a[j].x)
			{
				mins = j;
			}
		}
		if (mins != i)
		{
			Term temp = a[i];
			a[i] = a[mins];
			a[mins] = temp;
		}
	}
}

void SparseMatrix::newTranspose(SparseMatrix &B)
{//快速压缩
	B.terms = terms; B.rows = cols; B.cols = rows;
	//存放M中第col 列中非0元素个数
	int  num[10] = { 0 }, cpot[10] = { 1 };
	for (int i = 0; i < terms; ++i)
	{
		++num[a[i].y];
	}
	//存放M中第col列的第一个非0元素在T三元组的位置
	for (int i = 0; i + 1 < cols; ++i)
	{
		if (num[i + 1])
		{
			cpot[i + 1] = cpot[i] + num[i];
		}
		else
		{
			cpot[i + 1] = cpot[i];
		}
	}

	for (int i = 0; i < terms; ++i)
	{
		B.a[cpot[a[i].y] - 1].x = a[i].y;
		B.a[cpot[a[i].y] - 1].y = a[i].x;
		B.a[cpot[a[i].y] - 1].v = a[i].v;
		cpot[a[i].y]++;
	}
}
int main()
{
	SparseMatrix sm(6, 6);
	SparseMatrix sn(6, 6);
	std::cin >> sm;
	std::cin.get();//用来吸收(Enter)键
	std::cin >> sn;
	sm = sm + sn;
	std::cout << "sm + sn = \n" << sm << std::endl;



	sm.newTranspose(sn);
	std::cout << "newTranspose:" << sn << std::endl;


	sm.Transpose(sn);
	std::cout << "Transpose:" << sn << std::endl;


	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值