###### 稀疏矩阵相乘
#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;
}


#### 实现稀疏矩阵相乘C/C++

2016-10-14 20:34:44

#### 数据结构--稀疏矩阵（相乘）

2015-03-02 17:24:07

#### 稀疏矩阵利用三元组相乘（c语言）

2017-10-25 22:13:20

#### 稀疏矩阵与矩阵块乘法

2018-03-01 16:10:02

#### 顺序存储结构的三元组稀疏矩阵的乘法运算

2014-06-07 09:38:26

#### LeetCode 311. Sparse Matrix Multiplication（稀疏矩阵相乘）

2016-04-21 08:12:23

#### 数据结构C++实验之稀疏矩阵乘法

2017-12-16 17:41:35

#### 行逻辑链接的顺序表实现稀疏矩阵的相乘(Java语言描述)

2014-10-16 22:11:44

#### 稀疏矩阵乘法matlab

2012年06月04日 2KB 下载

#### 数据结构中的稀疏矩阵相乘问题

2010年04月19日 4KB 下载