稀释矩阵快速转置(三元组表示法 | 压缩存储)

本文介绍了如何使用C++编写一个名为Matt的类,用于处理稀疏矩阵,包括数据设置、正常转置和快速转置方法,展示了矩阵转置前后的内容显示。
//稀疏矩阵转置
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <iomanip>
using namespace std;
const int maxn = 10;

typedef int dataType;
typedef struct _Triple{
	int row;
	int col;
	dataType val;
	_Triple(){
	}
	_Triple(int row,int col,dataType val){
		this->row = row;
		this->col = col;
		this->val = val;
	}
	void opt(){
		printf("(%d,%d):%d\n",row,col,val);
	}
}Triple; 
class cmpPred{
	public:
		bool operator()(const Triple &triA,const Triple &triB){
			return triA.col < triB.col;//不加等号,保证算法稳定性 
		}
		//行优先矩阵表示,转置前按列序列号升序排列 
};

void trans(Triple &tri){
	swap(tri.row,tri.col);
}
class Matt{
	friend class cmpPred;
	friend void trans(Triple &tri);
	public:
		Matt(int rN,int cN,dataType c);
		int rN;
		int cN;
		int tN;
		int tNPerCol[maxn];
		int tNPot[maxn]; 
		dataType c;
		 
		Triple data[maxn];
		
		void nrmTrans(void);
		void fastTrans(void);
		
		void dataSetter(void);
		void showMatt(void);
		void showTri(void);
};
Matt::Matt(int rN,int cN,dataType c){
	this->rN = rN;
	this->cN = cN;
	this->c = c;
	this->tN = 0;	
}
void Matt::dataSetter(){
	
	int idx = 0;
	while(true){
		cout << setfill('-')<< setw(20)<< "ELEM"<< idx+1<<setfill('-')<<right<< setw(20)<<":"<< endl;
		int row;
		int col;
		dataType val;
		
		cout << "row:" << endl;
		cin >> row;
		
		cout << "col:" << endl;
		cin >> col;
		
		cout << "val:" << endl;
		cin >> val;
		
		Triple tri(row,col,val);
		data[idx++] = tri;
		
		tN++;
		
		cout << "----------------" << endl;
		cout << "1 continue   ||   default end" << endl;
		int sel;
		cin >> sel;
//		system("pause");
		system("cls");
		if(sel != 1){
			break;
		}
	}
	
	fill_n(tNPerCol,cN,0);
	int beg = cN;
	for(int i = 0;i < cN;i ++){
		tNPerCol[i] = count_if(data,data+tN,[i](const Triple &tri)->bool{return tri.col-1==i;});
		if(tNPerCol[i]!=0&&i<beg) beg = i;
	}
	
	fill_n(tNPot,cN,0);
	tNPot[beg] = 1;
	for(int i = beg+1;i < cN;i++){
		tNPot[i] = tNPot[i-1]+tNPerCol[i-1];
	}
}
void Matt::nrmTrans(){//时间换空间 
	swap(cN,rN);
	if(tN){
		sort(data,data+tN,cmpPred());
		for_each(data,data+tN,trans); 
	}
}
void Matt::fastTrans(){//空间换时间 
	if(tN){
		Triple temp[tN];
		int vis[cN] = {0};
		swap(rN,cN); 
		for(int i = 0;i < tN;i++){
			int idx = tNPot[data[i].col-1]+vis[data[i].col-1]-1;
			temp[idx] = data[i];//结构体支持等号赋值
			swap(temp[idx].col,temp[idx].row);
			vis[data[i].col-1]++;
		}
		for(int i = 0;i < tN;i++){
			data[i] = temp[i];
		} 
	}	
}
void Matt::showMatt(){ 
	for(int i = 0;i < rN;i++){
		for(int j = 0;j < cN;j++){
			Triple* triPtr = find_if(data,data+tN,[i,j](const Triple &tri)->bool{return (tri.row-1==i)&&(tri.col-1==j);});
			
			if((int)(triPtr-(data+tN))){
				cout << setw(3) << triPtr->val;
			}else cout << setw(3) << c;
		} 
		cout << endl;
	}
}
void Matt::showTri(){
	for(int i = 0;i < tN;i ++){
		data[i].opt();
	}
}
int main(){
	Matt matt(6,4,0);
//	Matt matt2(6,4,0);
	
	matt.dataSetter();
	cout << "转置前:" << endl;
	matt.showMatt();
	matt.showTri();
	
	cout << "转置后:" << endl;
	matt.fastTrans();
	matt.showMatt();
	matt.showTri();
	
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XNB's Not a Beginner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值