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

📄 matrix.cpp

📁 矩阵类:可运行矩阵间的加、减、乘以及矩阵与数的点乘;可计算矩阵的转置、秩、行列式、逆;其中求解矩阵逆用到了经典的高斯算法;求解行列式以及秩运用的是消元法。
💻 CPP
字号:
////////////////////////////////////////////////////////////////
//文件名: Matrix.h
//作者: 祁大江
//功能:矩阵类:可运行矩阵间的加、减、乘以及矩阵与数的点乘;可计算矩阵的转置、秩、行列式、逆;
//		其中求解矩阵逆用到了经典的高斯算法;求解行列式以及秩运用的是消元法。
//说明:本程序中数组的运算,都将二维数组转换为一维数组来进行计算的,方便传递参数;程序中的矩阵都是方阵。
////////////////////////////////////////////////////////////////
#define N 9  //定义矩阵元素的个数
#include<iostream.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#include"matrix.h"
Matrix::Matrix()
{
	list=new float[N];
	nElem=0;
}
void Matrix::Destroy()
{
	delete []list;
}
int Matrix::Elem(void)
{
	return nElem;
}
int Matrix::Elem(float elem)  //给矩阵元素赋值
{
	if(nElem<N)
	{
		list[nElem++]=elem;
		return nElem;
	}
	else
	{
		return 0;
	}
}
void Matrix::Print(void)
{
	for(int i=0;i<N;i++) 
	{
		cout<<list[i]<<'\t';
		if(((i+1)%int(sqrt(N)))==0)
		{
			cout<<endl;
		}
	}
	cout<<endl;
}
float Matrix::GetElem(int i) //返回矩阵中所要求的元素
{
	if((i>=0)&&(i<nElem))
	{
		return list[i];
	}
	else
	{
		return 0;
	}
}
/*int Matrix::zhi()
{
	int i,j,k;
	int t=0;
	float m;
	float temp[N*N]={0};
	int s=int(sqrt(N));
	for(i=0;i<sqrt(N);i++)
	{
		for(k=i+1;k<sqrt(N);k++)
		{
			for(j=0;j<sqrt(N);j++)
			{
				temp[t*int(sqrt(N))+j]=list[i*int(sqrt(N))+j]+list[k*int(sqrt(N))+j];
			}
			t++;
		}
	}
	cout<<"等比矩阵为:"<<endl;
	for(i=0;i<(N*(sqrt(N)-1))/2;i++) 
	{
		cout<<temp[i]<<'\t';
		if(((i+1)%int(sqrt(N)))==0)
		{
			cout<<endl;
		}
	}
	cout<<endl;
	for(i=0;i<(sqrt(N)*(sqrt(N)-1))/2;i++)
	{
		for(k=0;k<sqrt(N);k++)
		{
			m=temp[i*int(sqrt(N))]/list[k*int(sqrt(N))];
			for(j=1;j<sqrt(N);j++)
			{
				if((temp[i*int(sqrt(N))+j]/list[k*int(sqrt(N))+j])!=m)
				{
					break;
				}
			}
			if(j==sqrt(N))
			{
				s--;
			}
		}
	}
	return s;
}*/
int Matrix::zhi()//求矩阵的秩,没有找到经典的算法
{
	int i,j,k,t;
	float temp;
	int flg=0;
	int f;
	int s=0;
	if(list[0]==0)//确保迭代的第一个元素不为0
	{
		for(i=1;i<sqrt(N);i++) //行
		{
			for(k=0;k<sqrt(N);k++) //列
			{
				if(list[i*int(sqrt(N))+k]!=0) //找到一个不为0的元素
				{
					flg=1; //标志找到了不为0的元素
					//先交换行
					for(j=0;j<sqrt(N);j++)
					{
						temp=list[j];
						list[j]=list[i*int(sqrt(N))+j];
						list[i*int(sqrt(N))+j]=temp;
					}
					//再交换列
					for(j=0;j<sqrt(N);j++)
					{
						temp=list[j*int(sqrt(N))];
						list[j*int(sqrt(N))]=list[j*int(sqrt(N))+k];
						list[j*int(sqrt(N))+k]=temp;
					}
					break;
				}
			}
			if(flg==1)
			{
				break;
			}
		}
		if(flg==0)
		{
			//说明该矩阵是0矩阵,其秩为0
			return 0;
		}
	}
	/*cout<<"等价矩阵为:"<<endl;
	for(i=0;i<N;i++) 
	{
		cout<<list[i]<<'\t';
		if(((i+1)%int(sqrt(N)))==0)
		{
			cout<<endl;
		}
	}*/
	for(i=0;i<sqrt(N);i++)
	{
		f=0;
		if(i==0)
		{
			temp=list[i*int(sqrt(N))+i];
			for(j=0;j<sqrt(N);j++) //使对角线上的元素为1
			{
				list[i*int(sqrt(N))+j]/=temp;
				k=i;
			}
		}
		else
		{
			if(i>1)
			{
				temp=list[(i-1)*int(sqrt(N))+(i-1)];
				for(j=0;j<sqrt(N);j++)//使对角线上的元素为1
				{
					list[(i-1)*int(sqrt(N))+j]/=temp;
					k=i-1;
				}
			}
			for(t=i;t<sqrt(N);t++) //消元,把第i-1行乘一个系数依次往下加
			{
				temp=list[t*int(sqrt(N))+k];
				for(j=0;j<sqrt(N);j++)
				{
					list[t*int(sqrt(N))+j]-=list[(i-1)*int(sqrt(N))+j]*temp;
				}
			}
		}
		if(list[i*int(sqrt(N))+i]==0)//确保以后迭代的对角线元素不为0
		{
			for(k=i;k<sqrt(N);k++) //行
			{
				for(t=i;t<sqrt(N);t++)//列
				{
					if(list[k*int(sqrt(N))+t]!=0)//找到一个不为零的元素
					{
						f=1;
						//先换行
						for(j=i;j<sqrt(N);j++)
						{
							temp=list[i*int(sqrt(N))+j];
							list[i*int(sqrt(N))+j]=list[k*int(sqrt(N))+j];
							list[k*int(sqrt(N))+j]=temp;
						}
						//再换列
						for(j=i;j<sqrt(N);j++)
						{
							temp=list[j*int(sqrt(N))+i];
							list[j*int(sqrt(N))+i]=list[j*int(sqrt(N))+t];
							list[j*int(sqrt(N))+t]=temp;
						}
						break;
					}
				}
				if(f==1)//找到了不为零的元素,交换后就跳出
				{
					break;
				}
			}
			if (f==0)
			{
				//说明剩下的元素全为0,直接跳出整个for循环
				break;
			}
		}
	}
	for(i=0;i<sqrt(N);i++)//最后秩代为上三角阵后,每一行只要就一个元素不为0,该矩阵的秩就加1
	{
		for(j=0;j<sqrt(N);j++)
		{
			if(list[i*int(sqrt(N))+j]!=0)
			{
				s++;
				break;
			}

		}

	}
	/*cout<<"迭代为上三角矩阵为:"<<endl;
	for(i=0;i<N;i++) 
	{
		cout<<list[i]<<'\t';
		if(((i+1)%int(sqrt(N)))==0)
		{
			cout<<endl;
		}
	}*/
	return s;
}
float Matrix::hang()//求行列式,该算法还可以
{
	int i,j,k,t;
	float s=1.0;
	float temp=0;
	int flg=0;
	if(list[0]==0)//确保迭代的第一个元素不为0
	{
		for(i=1;i<sqrt(N);i++)
		{
			if(list[i*int(sqrt(N))]!=0)
			{
				flg=1;
				for(j=0;j<sqrt(N);j++)
				{
					temp=list[j];
					list[j]=list[i*int(sqrt(N))+j];
					list[i*int(sqrt(N))+j]=temp;
				}
				break;
			}
		}
		if(flg==0)//说明行列式为0
		{
			return 0;
		}
	}
	for(i=0;i<sqrt(N);i++)
	{
		flg=0;
		if(i==0)
		{
			temp=list[i*int(sqrt(N))+i];
			for(j=0;j<sqrt(N);j++)
			{
				list[i*int(sqrt(N))+j]/=temp;
				k=i;
			}
		}
		else
		{
			if(i>1)
			{
				temp=list[(i-1)*int(sqrt(N))+(i-1)];
				for(j=0;j<sqrt(N);j++)
				{
					list[(i-1)*int(sqrt(N))+j]/=temp;
					k=i-1;
				}
			}
			for(t=i;t<sqrt(N);t++)//消元
			{
				temp=list[t*int(sqrt(N))+k];
				for(j=0;j<sqrt(N);j++)
				{
					list[t*int(sqrt(N))+j]-=list[(i-1)*int(sqrt(N))+j]*temp;
				}
			}
		}
		if(list[i*int(sqrt(N))+i]==0)//确保以后迭代的对角线元素元素不为0
		{
			for(k=i+1;k<sqrt(N);k++)
			{
				if(list[k*int(sqrt(N))+i]!=0)
				{
					flg=1;
					for(j=0;j<sqrt(N);j++)
					{
						temp=list[i*int(sqrt(N))+j];
						list[i*int(sqrt(N))+j]=list[k*int(sqrt(N))+j];
						list[k*int(sqrt(N))+j]=temp;
					}
					break;
				}
			}
			if (flg==0)
			{
				return 0;
			}
		}
		s*=list[i*int(sqrt(N))+i];
	}
	return s;
}
void Matrix::ni()//求逆,经典的高斯算法
{
	int i,j,k,t;
	float ru[2*N]={0};
	float temp=0;
	int flg=0;
	//在该矩阵右边填充一个同阶的单位阵,为以下的求解作好准备
	for (i=0;i<sqrt(N);i++)
	{
		for(j=0;j<2*sqrt(N);j++)
		{
			if(j<sqrt(N))
			{
				ru[i*int(2*sqrt(N))+j]=list[i*int(sqrt(N))+j];
			}
			else
			{
				if(((j-i)-int(sqrt(N)))==0)
				{
					ru[i*int(2*sqrt(N))+j]=1;
				}
				else
				{
					ru[i*int(2*sqrt(N))+j]=0;
				}
			}
		}
	}
	/*cout<<"初始矩阵为:"<<endl;
	for(i=0;i<int(sqrt(N));i++)
	{
		for(j=0;j<2*int(sqrt(N));j++)
		{
			cout<<ru[i*int(2*sqrt(N))+j]<<'\t';
		}
		cout<<endl;
	}*/
	if(ru[0]==0)//确保迭代的第一个元素不为0
	{
		for(i=1;i<int(sqrt(N));i++)
		{
			if(ru[i*int(sqrt(N))]!=0)
			{
				flg=1;
				for(j=0;j<2*int(sqrt(N));j++)
				{
					temp=ru[j];
					ru[j]=ru[i*int(2*sqrt(N))+j];
					ru[i*int(2*sqrt(N))+j]=temp;
				}
				break;
			}
		}
		if (flg==0)//说明该矩阵不可逆,直接跳出 
		{
			return;
		}
	}
	//先迭代为一个上三角形
	for(i=0;i<int(sqrt(N));i++)
	{
		flg=0;
		if(i==0)
		{
			temp=ru[i*int(2*sqrt(N))+i];
			for(j=0;j<2*int(sqrt(N));j++)
			{
				ru[i*int(2*sqrt(N))+j]/=temp;
				k=i;
			}
		}
		else
		{
			if(i>1)
			{
				temp=ru[(i-1)*int(2*sqrt(N))+(i-1)];
				for(j=0;j<2*int(sqrt(N));j++)
				{
					ru[(i-1)*int(2*sqrt(N))+j]/=temp;
					k=i-1;
				}
			}
			for(t=i;t<int(sqrt(N));t++) //消元
			{
				temp=ru[t*int(2*sqrt(N))+k];
				for(j=0;j<2*int(sqrt(N));j++)
				{
					ru[t*int(2*sqrt(N))+j]-=ru[(i-1)*int(2*sqrt(N))+j]*temp;
				}
			}
		}
		if(ru[i*int(2*sqrt(N))+i]==0)//确保迭代后对角线上元素不为0
		{
			for(k=i+1;k<int(sqrt(N));k++)
			{
				if(ru[k*int(2*sqrt(N))+i]!=0)
				{
					flg=1;
					for(j=0;j<2*int(sqrt(N));j++)
					{
						temp=ru[i*int(2*sqrt(N))+j];
						ru[i*int(2*sqrt(N))+j]=ru[k*int(2*sqrt(N))+j];
						ru[k*int(2*sqrt(N))+j]=temp;
					}
					break;
				}
			}
			if (flg==0)//说明该矩阵不可逆,直接跳出
			{
				return ;
			}
		}
		if (i==(int(sqrt(N))-1))//把最后一行元素对角线上的元素化为1
		{
			temp=ru[i*int(2*sqrt(N))+i];
			for(j=0;j<2*int(sqrt(N));j++)
			{
				ru[i*int(2*sqrt(N))+j]/=temp;
			}
		}
	}
	/*cout<<"矩阵迭代为上三角形后为:"<<endl;
	for(i=0;i<int(sqrt(N));i++)
	{
		for(j=0;j<2*int(sqrt(N));j++)
		{
			cout<<ru[i*int(2*sqrt(N))+j]<<'\t';
		}
		cout<<endl;
	}*/
	//再转换为对角形
	for(i=int(sqrt(N))-1;i>=0;i--)
	{
		for(t=i-1;t>=0;t--)
		{
			temp=ru[t*int(2*sqrt(N))+i];
			for(j=0;j<2*int(sqrt(N));j++)
			{
				ru[t*int(2*sqrt(N))+j]-=ru[i*int(2*sqrt(N))+j]*temp;
			}
		}

	}
	/*cout<<"矩阵迭代为对角形后为:"<<endl;
	for(i=0;i<int(sqrt(N));i++)
	{
		for(j=0;j<2*int(sqrt(N));j++)
		{
			cout<<ru[i*int(2*sqrt(N))+j]<<'\t';
		}
		cout<<endl;
	}*/
	//从填充的矩阵中找出所求的逆阵
	for(i=0;i<int(sqrt(N));i++)
	{
		for(j=int(sqrt(N));j<2*int(sqrt(N));j++)
		{
			list[i*int(sqrt(N))+(j-int(sqrt(N)))]=ru[i*int(2*sqrt(N))+j];
		}
	}
}
void Matrix::dicheng(float alpha)
{
	for(int i=0;i<N;i++)
	{
		list[i]=alpha*list[i];
	}
}
void Matrix:: T() //转置
{
	int i,j;
	Matrix temp;
	for(i=0;i<sqrt(N);i++)
	{
		for(j=0;j<sqrt(N);j++)
		{
			temp[j*int(sqrt(N))+i]=list[i*int(sqrt(N))+j];
		}
	}
	for(i=0;i<sqrt(N);i++)
	{
		for(j=0;j<sqrt(N);j++)
		{
			list[i*int(sqrt(N))+j]=temp[i*int(sqrt(N))+j];
		}
	}
}
Matrix operator+(Matrix a,Matrix b)
{
	Matrix temp;
	for(int i=0;i<N;i++)
	{
		temp[i]=a[i]+b[i];
	}
	return temp;
}
Matrix operator-(Matrix a,Matrix b)
{
	Matrix temp;
	for(int i=0;i<N;i++)
	{
		temp[i]=a[i]-b[i];
	}
	return temp;
}
Matrix operator*(Matrix a,Matrix b)
{
	int i,j,k;
	Matrix temp;
	for(i=0;i<N;i++) //初始化为零
	{
		temp.Elem(0);
	}
	for(i=0;i<sqrt(N);i++)
	{
		for(j=0;j<sqrt(N);j++)
		{
			for(k=0;k<sqrt(N);k++)
			{
				temp[i*int(sqrt(N))+j]+=a[i*int(sqrt(N))+k]*b[k*int(sqrt(N))+j];
			}
		}
	}
	return temp;
}
float & Matrix::operator[](int index)
{
	if(index>=N||index<0)
	{
		cout<<"\nerror:下标"<<index<<"越界"<<endl;
		exit(2);
	}
	return list[index];
}
Matrix Matrix::operator =(Matrix &a)
{
	for(int i=0;i<N;i++)
	{
		list[i]=a[i];
	}
	return *this;
}
Matrix Matrix::operator *(float alpha)//点乘
{
	for(int i=0;i<N;i++)
	{
		list[i]=alpha*list[i];
	}
	return *this;
}
void main()
{
	Matrix list1,list2,list3;
	double time1=0;	//开始时间                
	double time2=0;	//结束时间	
	float ha=0;
	int z=0;
	float tmp1[9]={1,2,0,1,2,0,1,1,3};
	float tmp2[9]={1,2,3,4};
	time1=(double)clock();
	for(int i=0;i<N;i++) 
	{
		list1.Elem(tmp1[i]);
		list2.Elem(tmp2[i]);
	}
	list1.Print();
	list2.Print();
	z=list1.zhi();
	cout<<"矩阵秩为:"<<z<<endl;
	list3=list1*2;
	cout<<"矩阵点乘后为:"<<endl;
    list3.Print();
	list2.T();
	cout<<"矩阵转置后为:"<<endl;
	list2.Print();
	//list3=list1*list2;
	cout<<"矩阵相乘后为:"<<endl;
	list3.Print();
	ha=list2.hang();
	cout<<"矩阵行列式为:"<<ha<<endl;
	if(list1.hang()!=0)
	{
		list1.ni();
		cout<<"矩阵逆矩阵为:"<<endl;
		list1.Print();
	}
	else
	{
		cout<<"矩阵不可逆!不存在逆矩阵!"<<endl;
	}
	//cout<<list1.GetElem(list1.Elem()-1)<<endl;
	//list1.Destroy();
	time2=(double)clock(); 
	cout<<"运行所需时间为:"<<(time2-time1)/1000<<" 秒"<<endl; 
}

⌨️ 快捷键说明

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