稀疏矩阵相乘

原创 2013年12月03日 22:26:21
#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;
}


相关文章推荐

稀疏矩阵相乘

  • 2012年04月26日 16:14
  • 2KB
  • 下载

稀疏矩阵相乘C语言源码

  • 2012年05月16日 14:01
  • 2KB
  • 下载

(14)稀疏矩阵的压缩-三元组(相乘)

(1)因为position[i]表示B的第i行第一个非零元素在B.data中的序号,position[i+1]-1就表示第i行最后一个非零元素在B.data中的序号。为了表示B的最后一行最后一个非零元...

c语言+稀疏矩阵相乘

  • 2009年11月22日 00:05
  • 198KB
  • 下载

稀疏矩阵相加和相乘

  • 2015年11月21日 21:25
  • 3KB
  • 下载

稀疏矩阵三元组的相加相乘运算

代码如下: //矩阵三元组之矩阵相加 相乘 #include using namespace std; typedef int Elemtype; #define MAXSIZE 12...

数据结构--稀疏矩阵(相乘)

// RLSMatrix.cpp : Defines the entry point for the console application. /*-----CODE FOR FUN---------...

稀疏矩阵的运算(相乘,输出,转置,相加)

// Matrix.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include #include using namespace std; #def...
  • z1d9y0
  • z1d9y0
  • 2014年10月30日 18:00
  • 778
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:稀疏矩阵相乘
举报原因:
原因补充:

(最多只允许输入30个字)