#pragma once
class CMatrix
{
public:
CMatrix(void);
~CMatrix(void);
bool InitMatrix(int row=3, int col=2, int count_of_number=3);
private:
int m_nRow;
int m_nCol;
int m_nTotal;
struct Node
{
int row;
int col;
int val;
};
Node *m_pNode;
public:
void InputMatrix(void);
void OutPutMatrix(void);
void DefaultInit(void);
private:
int Find(int temprow, int tempcol);
public:
void FastReverse(void);
int Multiply(const CMatrix& matrixSource, CMatrix& matrixDest);
CMatrix(const CMatrix& matrix);
void DefaultInit1(void);
};
#include "StdAfx.h"
#include "Matrix.h"
CMatrix::CMatrix(void)
{
m_pNode = NULL;
}
CMatrix::~CMatrix(void)
{
if (NULL != m_pNode)
{
delete []m_pNode;
}
}
bool CMatrix::InitMatrix(int row, int col, int count_of_number)
{
m_nCol = col;
m_nRow = row;
m_nTotal = count_of_number;
m_pNode = new Node[count_of_number];
if (NULL == m_pNode)
{
return false;
}
return true;
}
void CMatrix::InputMatrix(void)
{
int row, col, val;
for (int i=0; i<m_nTotal; i++)
{
cout<<"请输入行:";
cin>>row;
cout<<"请输入列:";
cin>>col;
cout<<"请输入元素值:";
cin>>val;
m_pNode[i].row = row;
m_pNode[i].col = col;
m_pNode[i].val = val;
}
//DefaultInit();
}
void CMatrix::OutPutMatrix(void)
{
int nPos;
for (int row=0; row<m_nRow; row++)
{
for (int col=0; col<m_nCol; col++)
{
if ((nPos=Find(row, col)) != -1)
{
cout<<setw(4)<<left<<m_pNode[nPos].val<<" ";
}
else
{
cout<<setw(4)<<left<<0<<" ";
}
}
cout<<endl;
}
}
void CMatrix::DefaultInit(void)
{
m_pNode[0].row = 0;
m_pNode[0].col = 1;
m_pNode[0].val = 4;
m_pNode[1].row = 1;
m_pNode[1].col = 1;
m_pNode[1].val = 5;
m_pNode[2].row = 2;
m_pNode[2].col = 1;
m_pNode[2].val = 7;
}
int CMatrix::Find(int temprow, int tempcol)
{
for (int i=0; i<m_nTotal; i++)
{
if (m_pNode[i].row == temprow && m_pNode[i].col == tempcol)
{
return i;
}
}
return -1;
}
void CMatrix::FastReverse(void)
{
Node *pTemp = new Node[m_nTotal];
if (NULL == pTemp)
{
return;
}
//求稀疏矩阵每一列非零元素的个数
int *parrCol = new int[m_nCol+1];
if (NULL == parrCol)
{
return;
}
memset(parrCol, 0, sizeof(int)*(m_nCol+1));
int i;
for (i=0; i<m_nTotal; i++)
{
parrCol[m_pNode[i].col+1]++; //将前一列的非零元素个数放到后一列去
}
for (i=1; i<m_nCol+1; i++)
{
parrCol[i] += parrCol[i-1]; //设置每一列的第一个元素在稀疏矩阵中的位置
}
for (i=0; i<m_nTotal; i++)
{
int pos = parrCol[m_pNode[i].col]++;
pTemp[pos].row = m_pNode[i].col;
pTemp[pos].col = m_pNode[i].row;
pTemp[pos].val = m_pNode[i].val;
}
for (int i=0; i<m_nTotal; i++)
{
m_pNode[i].col = pTemp[i].col;
m_pNode[i].row = pTemp[i].row;
m_pNode[i].val = pTemp[i].val;
}
int temp = m_nRow;
m_nRow = m_nCol;
m_nCol = temp;
delete []pTemp;
delete []parrCol;
}
int CMatrix::Multiply(const CMatrix& matrixSource, CMatrix& matrixDest)
{
if (m_nCol != matrixSource.m_nRow)
{
return 0;
}
//初始化目标矩阵
matrixDest.m_pNode = new Node[m_nRow*matrixSource.m_nCol];
matrixDest.m_nCol = matrixSource.m_nCol;
matrixDest.m_nRow = m_nRow;
CMatrix matrixReverse = matrixSource;
matrixReverse.FastReverse(); //先将其倒转
//求稀疏矩阵每一列非零元素的个数
int *pArrRow = new int[m_nRow+1];
if (NULL == pArrRow)
{
return 0;
}
memset(pArrRow, 0, sizeof(int)*(m_nRow+1));
int i;
for (i=0; i<m_nTotal; i++)
{
pArrRow[m_pNode[i].row+1]++; //将前一行的非零元素个数放到后一行去
}
for (i=1; i<m_nRow+1; i++)
{
pArrRow[i] += pArrRow[i-1]; //设置每一行的第一个元素在稀疏矩阵中的位置
}
//倒转矩阵
int *pArrRowOfReverse = new int[matrixReverse.m_nRow+1];
if (NULL == pArrRowOfReverse)
{
return 0;
}
memset(pArrRowOfReverse, 0, sizeof(int)*(matrixReverse.m_nRow+1));
for (i=0; i<matrixReverse.m_nTotal; i++)
{
pArrRowOfReverse[matrixReverse.m_pNode[i].row+1]++; //将前一行的非零元素个数放到后一行去
}
for (i=1; i<matrixReverse.m_nRow+1; i++)
{
pArrRowOfReverse[i] += pArrRowOfReverse[i-1]; //设置每一行的第一个元素在稀疏矩阵中的位置
}
int pos;
int posOfReverse;
int indexMatrixDest=0;
for (int row=0; row<matrixDest.m_nRow; row++)
{
for(int col=0; col<matrixDest.m_nCol; col++)
{
int result=0;
pos = pArrRow[row];
posOfReverse = pArrRowOfReverse[col];
if (m_pNode[pos].row == row || matrixReverse.m_pNode[posOfReverse].row == col)
{
while(pos<pArrRow[row+1] && posOfReverse<pArrRowOfReverse[col+1])
{
if (m_pNode[pos].col == matrixReverse.m_pNode[posOfReverse].col)
{
result += m_pNode[pos].val*matrixReverse.m_pNode[posOfReverse].val;
pos++;
posOfReverse++;
}
else if (m_pNode[pos].col < matrixReverse.m_pNode[posOfReverse].col)
{
pos++;
}
else
{
posOfReverse++;
}
}
}
if (result != 0)
{
matrixDest.m_pNode[indexMatrixDest].val = result;
matrixDest.m_pNode[indexMatrixDest].col = col;
matrixDest.m_pNode[indexMatrixDest].row = row;
indexMatrixDest++;
}
}
}
matrixDest.m_nTotal = indexMatrixDest;
delete []pArrRow;
delete []pArrRowOfReverse;
return 1;
}
CMatrix::CMatrix(const CMatrix& matrix)
{
m_pNode = new Node[matrix.m_nTotal];
if (NULL == m_pNode)
{
return ;
}
m_nCol = matrix.m_nCol;
m_nRow = matrix.m_nRow;
m_nTotal = matrix.m_nTotal;
memcpy(m_pNode, matrix.m_pNode, sizeof(Node)*m_nTotal);
}
void CMatrix::DefaultInit1(void)
{
m_pNode[0].row = 0;
m_pNode[0].col = 0;
m_pNode[0].val = 4;
m_pNode[1].row = 0;
m_pNode[1].col = 2;
m_pNode[1].val = 5;
m_pNode[2].row = 0;
m_pNode[2].col = 3;
m_pNode[2].val = 4;
m_pNode[3].row = 1;
m_pNode[3].col = 0;
m_pNode[3].val = 5;
m_pNode[4].row = 1;
m_pNode[4].col = 1;
m_pNode[4].val = 3;
m_pNode[5].row = 2;
m_pNode[5].col = 0;
m_pNode[5].val = 7;
m_pNode[6].row = 2;
m_pNode[6].col = 3;
m_pNode[6].val = 7;
}
// SparseMatrix.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "Matrix.h"
int _tmain(int argc, _TCHAR* argv[])
{
CMatrix matrix;
matrix.InitMatrix(5, 8, 4);
matrix.InputMatrix();
//matrix.DefaultInit();
cout<<"稀疏矩阵如下:"<<endl;
matrix.OutPutMatrix();
matrix.FastReverse();
cout<<"稀疏矩阵转置后如下:"<<endl;
matrix.OutPutMatrix();
CMatrix matrixSource, matrixDest;
matrixSource.InitMatrix(5, 4, 3);
matrixSource.InputMatrix();
//matrixSource.DefaultInit1();
cout<<"稀疏矩阵如下:"<<endl;
matrixSource.OutPutMatrix();
matrix.Multiply(matrixSource, matrixDest);
cout<<"稀疏矩阵乘积如下:"<<endl;
matrixDest.OutPutMatrix();
return 0;
}