矩阵问题总结

一,对称矩阵的压缩存储:

1,

设一个N*N的方阵A,A中任意元素Aij,当且仅当Aij == Aji(0 <= i <= N-1 && 0 <= j <= N-1),则矩阵A是对称矩阵。以矩阵的对角线为分隔,分为上三角和下三角。
它存储时只要存储上三角或者下三角,所以只需要存储n(n+1)/2个数据。
一般采用下三角储存:i>=j。a[i][j]=array[i*(i+1)/2+j]。
2,

3,
#pragma once


#include<iostream>
using namespace std;


template<class T>
class SymmetricMatrix
{
public:
SymmetricMatrix(int* a, size_t size, size_t n)
: _a(new T[size*(size+1)/2])
, _size(size*(size + 1) / 2)
, _n(size)
{
size_t index = 0;
for (size_t i = 0; i < size; ++i)
{
for (size_t j = 0; j < size; ++j)
{
if(i >= j)
{
_a[index++] = a[i*size + j];
}
else
{
break;
}
}
}
}
~SymmetricMatrix()
{
if (_a)
{
delete[] _a;
_a = NULL;
_size = 0;
}
}


void Display()
{
for (size_t i = 0; i < _n; ++i)
{
for (size_t j = 0; j < _n; ++j)
{
if (i >= j)
{
cout << _a[i*(i + 1) / 2 + j] << " ";
}
else
{
cout << _a[j*(j + 1) / 2 + i] << " ";
}
}
cout << endl;
}
cout << endl;
}


T& Access(size_t i, size_t j)
{
if (i < j)
{
swap(i, j);
}
return _a[i*(i + 1) / 2 + j];
}
private:
T* _a;
size_t _size;
size_t _n;
};


void TestSymmetricMatrix()
{
int a[5][5] = { { 0, 1, 2, 3, 4 },
               { 1, 0, 1, 2, 3 },
               { 2, 1, 0, 1, 2 },
               { 3, 2, 1, 0, 1 },
               { 4, 3, 2, 1, 0 }
};
SymmetricMatrix<int> sm((int*)a, 5, 5);
sm.Display();
}


#define _CRT_SECURE_NO_WARNINGS 1

#include"Matrix.h"
int main()
{
TestSymmetricMatrix();
system("pause");
return 0;
}

4,




二,稀疏矩阵的压缩存储:

1,
      M*N阶矩阵,矩阵中有效值的个数远远小于无效只得个数,且这些数的分布没有规律。
2,
  压缩存储值存储极少的有效值,使用{row,col,value}三元组来存储这些有效值,并且按照行优先级以此存放。
3,

存储为{0,0,1}{0,2,3}{0,4,5}{3,0,1}{3,2,3}{3,4,5}
4,
template<class T>
struct Triplr  //三元组
{
T _value;
size_t _row;
size_t _col;
Triplr(T value, size_t row, size_t col)
: _value(value)
, _col(col)
, _row(row)
{}




};


template<class T>
class SparseMatrix
{
public:


SparseMatrix(T*a, size_t m, size_t n, const T& invalid)
: _rowsize(m)
, _colsize(n)
, _invalid(invalid)
{
for (size_t i = 0; i < m; ++i)
{
for (size_t j = 0; j < n; ++j)
{
if (a[i*n + j] != _invalid)
{
_a.push_back(Triplr<T>(a[i*n + j], i, j));
}
}
}
}
void Display()
{
size_t index = 0;
for (size_t i = 0; i < _rowsize; ++i)
{
for (size_t j = 0; j < _colsize; ++j)
{
if (index<_a.size() && _a[index]._row == i&&_a[index]._col == j)
{
cout << _a[index]._value << " ";
index++;
}
else
{
cout << _invalid <<" ";
}
}
cout << endl;
}
cout << endl;
}

private:
vector<Triplr<T>> _a;
size_t _rowsize;
size_t _colsize;
T _invalid;
};
void TestSparseMatrix()
{
int a[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 }
};
SparseMatrix<int> Xm((int*)a, 6, 5,0);
Xm.Display();
}
5,



三,矩阵的转置:
1,
将原矩阵的行列对换,也就是[i][j]变换为[j][i]上的数据互换。
2,普通转置
SparseMatrix<T>Transport()
{
SparseMatrix<T> tmp;
tmp._colsize = _rowsize;
tmp._rowsize = _colsize;
tmp._invalid = _invalid;


for (size_t i = 0; i < _colsize; ++i)
{
size_t index = 0;
while (index < _a.size())
{
if (_a[index]._col == i)
{
Triplr<T> t;
t._value = _a[index]._value;
t._col = _a[index]._row;
t._row = _a[index]._col;
tmp._a.push_back(t);
}
index++;
}
}
return tmp;
}

4,快速转置,

SparseMatrix<T>FastTransport()
{
SparseMatrix<T> tmp;
tmp._colsize = _rowsize;
tmp._rowsize = _colsize;
tmp._invalid = _invalid;


int *rowcount = new int[tmp._colsize];
int *rowstart = new int[tmp._colsize];
memset(rowcount, 0, sizeof(int)*_colsize);
memset(rowstart, 0, sizeof(int)*_colsize);
size_t index = 0;
while (index < _a.size())
{
rowcount[_a[index]._col]++;
index++;
}
rowstart[0] = 0;
for (size_t i = 1; i < _colsize; ++i)
{
rowstart[i] = rowstart[i - 1] + rowcount[i - 1];
//本行的起始位置=上一行的起始位置+上一行的有效数据数量
}
index=0;
tmp._a.resize(_a.size());
while (index < _a.size())
{
size_t rowindex = _a[index]._col;
int & start = rowstart[rowindex];
Triplr<T> t;
t._value = _a[index]._value;
t._col = _a[index]._row;
t._row = _a[index]._col;
   tmp._a[start++] = t;
++index;
}
return tmp;
}
5,
(1),普通转置


(2),快速转置


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值