⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matrix.cpp

📁 矩阵相乘问题的算法源程序
💻 CPP
字号:
// Matrix.cpp: implementation of the CMatrix class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MatrixMul.h"
#include "Matrix.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMatrix operator + (CMatrix & A,CMatrix & B)
{
	CMatrix C;
	if ((A._Col==B._Col)&&(A._Row==B._Row))
	{
		C._Col=A._Col;
		C._Row=A._Row;
		C.InitMatrix();
		for (int i=0;i<A._Row;i++)
			for (int j=0;j<A._Col;j++)
				C.pMatrix[i][j]=A.pMatrix[i][j]+B.pMatrix[i][j];
		return (C);
	}
	else
		return (C);
}
CMatrix operator - (CMatrix & A,CMatrix & B)
{
	CMatrix C;
	if ((A._Col==B._Col)&&(A._Row==B._Row))
	{
		C._Col=A._Col;
		C._Row=A._Row;
		C.InitMatrix();
		for (int i=0;i<A._Row;i++)
			for (int j=0;j<A._Col;j++)
				C.pMatrix[i][j]=A.pMatrix[i][j]-B.pMatrix[i][j];
		return (C);
	}
	else
		return (C);
}
void CMatrix::SplitMatrix(CMatrix & A11, CMatrix & A12, CMatrix & A21, CMatrix & A22)
{
	int Desc;
	int SubCol,SubRow;
	Desc=this->_Col/2;
	for (SubRow=0;SubRow<Desc;SubRow++)
		for (SubCol=0;SubCol<Desc;SubCol++)
		{
			//A11	
			A11.pMatrix[SubRow][SubCol]=this->pMatrix[SubRow+   0][SubCol+   0];
			//A12
			A12.pMatrix[SubRow][SubCol]=this->pMatrix[SubRow+   0][SubCol+Desc];
			//A21
			A21.pMatrix[SubRow][SubCol]=this->pMatrix[SubRow+Desc][SubCol+   0];
			//A22
			A22.pMatrix[SubRow][SubCol]=this->pMatrix[SubRow+Desc][SubCol+Desc];
		}
	return;
}
void CMatrix::IntegrateMatrix(CMatrix & A11, CMatrix & A12, CMatrix & A21, CMatrix & A22)
{
	if ((A11._Col!=_Col/2)||(A12._Col!=_Col/2)||(A21._Col!=_Col/2)||(A22._Col!=_Col/2))
	{
		TRACE("程序设计出错!\n");
		return;
	}
	int Desc;
	int SubCol,SubRow;
	Desc=this->_Col/2;
	for (SubRow=0;SubRow<Desc;SubRow++)
		for (SubCol=0;SubCol<Desc;SubCol++)
			{
				//A11	
				this->pMatrix[SubRow+   0][SubCol+   0]=A11.pMatrix[SubRow][SubCol];
				//A12
				this->pMatrix[SubRow+   0][SubCol+Desc]=A12.pMatrix[SubRow][SubCol];
				//A21
				this->pMatrix[SubRow+Desc][SubCol+   0]=A21.pMatrix[SubRow][SubCol];
				//A22
				this->pMatrix[SubRow+Desc][SubCol+Desc]=A22.pMatrix[SubRow][SubCol];
			}
	return;
}
CMatrix operator * (CMatrix & A,CMatrix & B)
{
	CMatrix C;
	if (A._Col==B._Row)
	{
		//这里如果满足使用Strassen算法则使用该算法进行乘法运算
		if ((A._Row==A._Col)&&(B._Row==B._Col)&&(A._Row%2==0))/*A,B同样是方阵,而且长度可以被2整除*/
		{
			int Desc;
			CMatrix A11,A12,A21,A22;
			CMatrix B11,B12,B21,B22;
			CMatrix C11,C12,C21,C22;
			Desc=A._Col/2;
			A11._Row=Desc; A11._Col=Desc;A11.InitMatrix();
			A12._Row=Desc; A12._Col=Desc;A12.InitMatrix();
			A21._Row=Desc; A21._Col=Desc;A21.InitMatrix();
			A22._Row=Desc; A22._Col=Desc;A22.InitMatrix();
			A.SplitMatrix(A11,A12,A21,A22);
			
			B11._Row=Desc; B11._Col=Desc;B11.InitMatrix();
			B12._Row=Desc; B12._Col=Desc;B12.InitMatrix();
			B21._Row=Desc; B21._Col=Desc;B21.InitMatrix();
			B22._Row=Desc; B22._Col=Desc;B22.InitMatrix();
			B.SplitMatrix(B11,B12,B21,B22);
			
			C11._Row=Desc; C11._Col=Desc;C11.InitMatrix();
			C12._Row=Desc; C12._Col=Desc;C12.InitMatrix();
			C21._Row=Desc; C21._Col=Desc;C21.InitMatrix();
			C22._Row=Desc; C22._Col=Desc;C22.InitMatrix();
			
			C._Col=A._Col;
			C._Row=A._Row;
			C.InitMatrix();
			C.SplitMatrix(C11,C12,C21,C22);

			CMatrix M1,M2,M3,M4,M5,M6,M7;
			M1._Col=Desc;M1._Row=Desc;M1.InitMatrix();
			M2._Col=Desc;M2._Row=Desc;M2.InitMatrix();
			M3._Col=Desc;M3._Row=Desc;M3.InitMatrix();
			M4._Col=Desc;M4._Row=Desc;M4.InitMatrix();
			M5._Col=Desc;M5._Row=Desc;M5.InitMatrix();
			M6._Col=Desc;M6._Row=Desc;M6.InitMatrix();
			M7._Col=Desc;M7._Row=Desc;M7.InitMatrix();

			M1=A11*(B12-B22);
			M2=(A11+A12)*B22;
			M3=(A21+A22)*B11;
			M4=A22*(B21-B11);
			M5=(A11+A22)*(B11+B22);
			M6=(A12-A22)*(B21+B22);
			M7=(A11-A21)*(B11+B12);

			C11=M5+M4-M2+M6;
			C12=M1+M2;
			C21=M3+M4;
			C22=M5+M1-M3-M7;
			C.IntegrateMatrix(C11,C12,C21,C22);

			return C;
		}
		else
		{
			//如果不满足使用Strassen算法,则直接相乘
			C._Row=A._Row;
			C._Col=B._Col;
			C.InitMatrix();
			for (int ARow=0;ARow<A._Row;ARow++)
				for (int BCol=0;BCol<A._Col;BCol++)
				{
					C.pMatrix[ARow][BCol]=0;
					for (int i=0;i<A._Col;i++)
						C.pMatrix[ARow][BCol]+=A.pMatrix[ARow][i]*B.pMatrix[i][BCol];
				}
			return C;
		}
	}
	else
		return (C);
}

CMatrix::CMatrix()
{
	//如果什么都没有给出,则什么都不作
	MatrixFile="";
	_Col=0;
	_Row=0;
	pMatrix=NULL;
	pMem=NULL;
}
CMatrix::CMatrix(char * _MatrixFile)
{
	//如果给出矩阵文件,则进行矩阵的初始化
	MatrixFile=_MatrixFile;
	_Col=0;
	_Row=0;
	pMatrix=NULL;
	pMem=NULL;
}
CMatrix::CMatrix(CMatrix &A)
{
	_Col=A._Col;
	_Row=A._Row;
	InitMatrix();
	for (int i=0;i<A._Row;i++)
		for (int j=0;j<A._Col;j++)
			pMatrix[i][j]=A.pMatrix[i][j];
}

CMatrix::~CMatrix()
{
	if (pMatrix!=NULL) delete[] pMatrix;
	if (pMem!=NULL)    delete[] pMem;
}

void CMatrix::InitMatrix()
{
	int i;
	if ((_Col==0)||(_Row==0)) 
	{
		TRACE("矩阵数据有问题!\n");
		return;
	}
	pMem=new double [_Col*_Row];
	pMatrix=new double * [_Row];
	for (i=0;i<_Row;i++)
		pMatrix[i]=&pMem[i*_Col];
	return;
}
void CMatrix::GetMatrixValue()
{
	if (MatrixFile.GetLength()==0) 
	{
		TRACE("矩阵数据文件是空!\n");
		return; 
	}
	//得到矩阵的行数和列数
	char Buffer[1024];
	GetPrivateProfileString("script","Row","0",Buffer,1024,MatrixFile);
	_Row=atoi(Buffer);
	GetPrivateProfileString("script","Col","0",Buffer,1024,MatrixFile);
	_Col=atoi(Buffer);
	InitMatrix();
	//把文件中的数据复制到动态生成的数组中
	/*
		CString strHello;
		CString SubStr;
		strHello="0;1;2;3;4;5;6;7;8;9";
		SubStr=strHello.SpanExcluding(";");
		strHello=strHello.Right(strHello.GetLength()-SubStr.GetLength()-1);
		SubStr=strHello.SpanExcluding(";");
		
	 */
	char DataBuf[1024];
	CString mainStr,subStr;
	for (int i=0;i<=_Row-1;i++)
	{
		//此处Buffer要清空一下
		memset(Buffer,(int)('\0'),1024*sizeof(char));//清零
		_itoa(i,Buffer,1024);
		CString TmpStr(CString("Row")+Buffer);
		memset(Buffer,(int)('\0'),1024*sizeof(char));//清零
		for (int j=0;j<TmpStr.GetLength();j++)
			Buffer[j]=TmpStr[j];
		/*以上,得到data区内每个行的行标记,例如:'Row0','Row1'....注意从零开始*/
		memset(DataBuf,(int)('\0'),1024*sizeof(char));//清零
		GetPrivateProfileString("Data",Buffer,"0",DataBuf,1024,MatrixFile);
		//提取每一行的各各数字,要求每个数字之间的分割使用','
		mainStr=DataBuf;
		for (int k=0;k<_Col;k++)
		{
			subStr=mainStr.SpanExcluding(",");
			mainStr=mainStr.Right(mainStr.GetLength()-subStr.GetLength()-1);
			pMatrix[i][k]=atof(subStr);
		}
	}
	return;
}
CMatrix & CMatrix::operator = (CMatrix & A)
{
	this->_Col=A._Col;
	this->_Row=A._Row;
	this->InitMatrix();
	for (int i=0;i<A._Row;i++)
		for (int j=0;j<A._Col;j++)
			this->pMatrix[i][j]=A.pMatrix[i][j];
	return *this;
}

void CMatrix::WriteMatrix()
{
	CString Section;
	CString Data;
	char    Buffer[1024];
	char    Value[1024];
	if (MatrixFile=="")
	{
		TRACE("用来存放结果的矩阵文件不能是空");
		return;
	}
	//注意此处的使用'itoa'的不同形式
	memset(Buffer,(int)('\0'),1024*sizeof(char));//清零
	itoa(_Row,Buffer,1024);
	WritePrivateProfileString("script","Row",Buffer,MatrixFile);

	memset(Buffer,(int)('\0'),1024*sizeof(char));//清零
	WritePrivateProfileString("script","Col",itoa(_Col,Buffer,1024),MatrixFile);
	for (int i=0;i<_Row;i++)
	{
		memset(Buffer,(int)('\0'),1024*sizeof(char));//清零
		Section="";
		Section+="Row";
		itoa(i,Buffer,1024);
		Section+=Buffer;
		for (int Strlen=0;Strlen<Section.GetLength();Strlen++)
			Buffer[Strlen]=Section[Strlen];
		Section="";
		for(int j=0;j<_Col;j++)
		{
			memset(Value,(int)('\0'),1024*sizeof(char));//清零
			sprintf(Value,"%f,",pMatrix[i][j]);
			Section+=Value;
		}
		Data=Section.Left(Section.GetLength()-1);//去掉最后一个','号
		printf("%s\n",Section);
		WritePrivateProfileString("data",Buffer,Data,MatrixFile);
	}
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -