您的位置:首页 > 编程语言 > C语言/C++

稀疏矩阵三元组方式压缩存储 c++模板类实现

2017-03-19 00:05 399 查看
稀疏矩阵:http://baike.baidu.com/link?url=jGMCgHbE_Ym0-52lvX_wzegjyQLt1oB_acE-m1w4AixVI-9LaPxeIh4YO3g6vdhrWVNLSpw3IEM4HX5f7rzEtsd0OJNBlbV2Soi2EneQfkIFgRCJz7_oqOPnOMYUBk8-

上篇博文提到了利用对称矩阵的特点进行压缩存储技术以达到节省空间的目的

现在我们来看看稀疏矩阵的压缩存储,

因其特点,不能像对称矩阵一样进行存储,  我们采用三元组方式压缩存储稀疏矩阵

定义一个三元组结构 存储有效数据的 行 列 以及 数值信息

遍历原数组 将    有效数字的信息存放在三元组中 (程序中无效数字当0对待  其余数字为有效数字)

即三元组只存放了有效数字的信息, 将稀疏矩阵进行了压缩,节省了存储空间

如要通过三元组信息还原原矩阵也很简单,这里不实现,只是把原矩阵信息打印出来,不进行还原

.h:

#include <vector>

template<class T>
struct Triple
{
size_t _row; //struct 默认为public 。 若为private则第52行编译不通过
size_t _col;
T _value;

Triple( size_t row, size_t col, const T& value )
:_row( row )
,_col( col )
,_value( value )
{}
};

template<class T>
class SparseMatrix
{
protected:
vector<Triple<T>> _matrix; //用 vector 容器 存放三元组
size_t _m;
size_t _n;
T _invalid;

public:
SparseMatrix( T* a, size_t m, size_t n, const T& invalid = T( ) )//内置类型,自己传参。 类类型,让它(T())调用自己类的默认构造函数,自己构造一个默认值
:_m( m )
,_n( n )
,_invalid( invalid )
{
for ( size_t i = 0; i < m; ++i ) //用m而不是_m
{
for ( size_t j = 0; j < n; ++j )
{
if ( invalid != a[i * n + j] ) //此处有坑,i*n(每列元素数) 而不是 i*m(每行元素数)
{
Triple<T> t( i, j, a[i * n + j] );//构建三元组对象

_matrix.push_back( t ); //注意为 push_back
}
}
}
}

void Display( ) //不用传参数,直接用私有数据成员
{
size_t index = 0;

for ( size_t i = 0; i < _m; ++i ) //所以此处使用_m而不是m
{
for ( size_t j = 0; j < _n; ++j )
{
if ( (index < _matrix.size( )) //以免越界
&&(i == _matrix[index]._row)
&&(j == _matrix[index]._col) )
{
cout << _matrix[index]._value << " ";

++index;
}
else
{
cout << 0 << " ";
}
}

cout << endl;
}

cout << endl; //一般来说.h头文件中不要出现 endl. 当然,此处例外!
}
};

.cpp:
#include <windows.h>
#include <iostream>
using namespace std;

#include "yy.h"

void test( );

int main( )
{
test( );

system( "pause" );

return 0;
}

void test( )
{
int a[6][5] = //二维数组底层实现为一维数组存储
{
{ 1, 0, 2, 0, 0 },
{ 1, 0, 1, 0, 3 },
{ 2, 0, 0, 1, 2 },
{ 3, 0, 1, 0, 0 },
{ 4, 0, 2, 0, 0 },
{ 0, 3, 4, 0, 0 },
};

SparseMatrix<int> sm((int*)a, 6, 5, 0); //所以 (int*)a. 注意模板类情形下怎么创建一个对象

sm.Display( );
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息