稀疏矩阵的基本操作
来源:互联网 发布:火锅烧烤网络营销策划 编辑:程序博客网 时间:2024/05/16 15:48
#include<iostream>#include<vector>#include<assert.h>#include<string.h>using namespace std;template <typename T>class SparseMatrix{public://构造SparseMatrix(){}SparseMatrix(int* arr,size_t row,size_t col,const T& invalid):_row(row),_col(col),_invalid(invalid) { for(size_t i=0;i<_row;i++) { for(size_t j=0;j<_col;j++){ if(arr[i*_col+j]!=_invalid) { _sm.push_back(Trituple<T>(i,j,arr[i*_col+j])); }} } } //访问//方法1:/*T& Access(size_t row,size_t col){ for(size_t i=0;i<_sm.size();i++) { if(_sm[i]._row==row && _sm[i]._col==col) return _sm[i]._data; } return _invalid;}*///方法2:迭代器 T& Access(size_t row,size_t col) { //定义迭代器 vector<Trituple<T>>::iterator it=_sm.begin(); while(it!=_sm.end()) { if(it->_row ==row && it->_col==col) return it->_data; ++it; } return _invalid; } //输出重定向。友元函数不是类成员函数,所以要写模板参数列表 template<typename T> friend ostream& operator<<(ostream& _cout,SparseMatrix<T> sm) { //方法1:访问Access(),循环多,开销大 /* for(size_t i=0;i<sm._row;i++) {for(size_t j=0;j<sm._col;j++) { _cout<<sm.Access(i,j)<<" "; }_cout<<endl; }*/ //方法2: size_t index=0; for(size_t i=0;i<sm._row;i++) { for(size_t j=0;j<sm._col;j++) {//index会越界,所以需要判断if(index<sm._sm.size() && sm._sm[index]._row==i && sm._sm[index]._col==j)_cout<<sm._sm[index++]._data<<" ";else_cout<<sm._invalid<<" "; } _cout<<endl; } return _cout; } //逆置 SparseMatrix<T> Transport() { SparseMatrix<T> sm; sm._row=_col; sm._col=_row; sm._invalid=_invalid; //有问题:不符合“以行优先存储”的规定,打印出来有问题 /*for(size_t i=0;i<_sm.size();i++) { sm._sm.push_back(Trituple<T>(_sm[i]._col,_sm[i]._row,_sm[i]._data)); }*/ for(size_t i=0;i<_col;i++)//找原矩阵的每列的有效元素-》为新矩阵的每行的元素 { vector<Trituple<T>>::iterator it=_sm.begin(); while(it!=_sm.end()) { if(i==it->_col) sm._sm.push_back(Trituple<T>(i,it->_row,it->_data)); ++it; } } return sm; } //快速逆置 SparseMatrix<T> FastTransport() { SparseMatrix<T> sm; sm._row=_col; sm._col=_row; sm._invalid=_invalid; //开辟新空间 sm._sm.resize(_sm.size()); //统计每列的有效值个数 int* pCount=new int[_col]; memset(pCount,0,_col*sizeof(pCount[0]));//清零 for(size_t i=0;i<_sm.size();i++) { pCount[_sm[i]._col]++; } //原矩阵的每列(即转置后的每行)在新矩阵的其实位置 int* pAddr=new int[_col]; memset(pAddr,0,_col*sizeof(pAddr[0])); for(size_t i=1;i<_sm.size();i++) { pAddr[i]=pAddr[i-1]+pCount[i-1]; } //放元素到新空间 for(size_t i=0;i<_sm.size();i++) { int& addr=pAddr[_sm[i]._col]; sm._sm[addr]=Trituple<T>(_sm[i]._col,_sm[i]._row,_sm[i]._data); addr++; } return sm; } //矩阵加法 SparseMatrix<T> operator+(const SparseMatrix<T>& sm) { assert(_row==sm._row && _col==sm._col); SparseMatrix<T> ret; ret._col=_col; ret._row=_row; ret._invalid=_invalid; int LeftAddr=0; int RightAddr=0; int Lidex=0; int Ridex=0; while(Lidex<_sm.size() && Ridex<sm._sm.size()) { LeftAddr=_sm[Lidex]._row*_col+_sm[Lidex]._col; RightAddr=sm._sm[Ridex]._row*_col+sm._sm[Ridex]._col;if(LeftAddr <RightAddr){ret._sm.push_back(_sm[Lidex]);Lidex++;}else if(LeftAddr >RightAddr){ret._sm.push_back(sm._sm[Ridex]);Ridex++;}else{ Trituple<T> temp(_sm[Lidex]);temp._data+=sm._sm[Ridex]._data;if(temp._data!= _invalid)ret._sm.push_back(temp);Lidex++;Ridex++;} } while(Lidex <_sm.size()) { ret._sm.push_back(_sm[Lidex++]); } while(Ridex <sm._sm.size()) { ret._sm.push_back(sm._sm[Ridex++]); } return ret; }private://三元组存储template <typename T>struct Trituple{Trituple(size_t row,size_t col,const T& data):_row(row),_col(col),_data(data){}Trituple(){} size_t _row; size_t _col; T _data;};private:size_t _row;size_t _col;T _invalid;//无效值vector<Trituple<T>> _sm;};int main(){ int arr[6][5]={{1,0,3,0,5}, {0,0,0,0,0}, {0,0,0,0,0}, {1,0,-3,0,5}, {0,0,0,0,0}, {0,0,0,0,0},}; int arr1[6][5]={{0,0,3,0,5}, {0,0,0,0,0}, {0,0,0,0,0}, {1,0,3,0,5}, {0,0,0,1,0}, {0,0,0,0,0},}; SparseMatrix<int> sm((int*)arr,sizeof(arr)/sizeof(arr[0]),sizeof(arr[0])/sizeof(arr[0][0]),0); SparseMatrix<int> sm1((int*)arr1,sizeof(arr1)/sizeof(arr1[0]),sizeof(arr1[0])/sizeof(arr1[0][0]),0);//cout<<sm.Access(3,2)<<endl; cout<<sm<<endl;cout<<sm1<<endl;cout<<sm+sm1<<endl;//cout<<sm.Transport()<<endl;//cout<<sm.FastTransport()<<endl; return 0;}
0 0
- 稀疏矩阵的基本操作
- 数据结构 稀疏矩阵的基本操作
- 稀疏矩阵的操作
- 十字链表表示稀疏矩阵的基本操作
- 稀疏矩阵的压缩存储和基本操作
- 稀疏矩阵的基本运算
- 稀疏矩阵的基本运算
- 稀疏矩阵的乘法操作
- 稀疏矩阵的乘法操作
- 稀疏矩阵的简单操作
- 稀疏矩阵的三元组顺序表存储表示及基本操作
- 稀疏矩阵三元组的操作
- 一步一步复习数据结构和算法基础-稀疏矩阵基本操作
- 稀疏矩阵操作
- 稀疏矩阵操作
- 稀疏矩阵的转置操作及其乘法操作
- 关于稀疏矩阵的压缩存储与基本运算
- 稀疏矩阵的各种基本运算并加法乘法
- 百度面试题之查找最小的K个元素
- HTML相关知识---《基于R语言的自动数据收集》
- height、clientHeight、scrollHeight、offsetHeight区别
- 敌兵布阵 (线段树 单点更新)
- 神经网络的优化算法选择
- 稀疏矩阵的基本操作
- 三层
- Ubuntu vim安装插件YouCompleteMe
- 4412驱动-input 输入子系统
- flume 自定义拦截器实现多行读取日志
- linux驱动开发之字符设备框架 -调用过程分析
- spring装配bean的三种方式
- 论文笔记 understanding deep learning requires rethinking generalization
- ajax,json获取action,html获取session中的值,显示登录名