#include <iostream>
#include <math.h>
#include <malloc.h>
#include <iomanip>
using namespace std;
int *ZeroOfRow; //用来存储行从开头起所具有的数据为0 的元素的个数
int *IfZeroOfRow; //IfZeroOfRow数组中只存储0或1,用来标识某列的数据是否为0
void printmat(float *p,int m,int n); //输出矩阵
void CheckZeroOfEveryRow(float *a,int m,int n); //统计每行从开头起所具有的数据为0的元素的个数并赋给数组ZerosOfRow
void Multiply(float *p,int m,int n,int k,float kj); //使某个数据变为1
void Judge(float *p,int m,int n,int j); //判定某列的数据是否为0,并将1或0赋给数组IfZerosOfRow
void Minus(float *p,int m,int n,int a,int b,float Rb); //b行的数据减去a行的数据与b行该列数据的乘积,将所得的差值再依次赋给b行的数据
void ExchangeRow(float *a,int m,int n,int h,int tag); //交换两行的数据
void mul_row(float *a,float k,int n); //矩阵的一行做乘法运算
void add_row(float *a1,float *a2,int k,int n); //矩阵的一行做加法运算
int gfrank(float *p,int m,int n); //求矩阵的秩
//void printxxx(int *p,int n);
void main()
{
int r1,r2,i,j,min,k,k1,tag,m,n,x=0;float t;
float *Matrix; //用于存放增广矩阵
float *CoefficientMatrix; //用于存放系数矩阵
cout<<"请输入增广矩阵的行数和列数: ";
cin>>m>>n;
cout<<"m="<<m<<",n="<<n<<endl;
ZeroOfRow=(int *)malloc(m*(sizeof(int)));
IfZeroOfRow=(int *)malloc(m*(sizeof(int)));
Matrix=(float *)malloc(m*n*(sizeof(float)));
CoefficientMatrix=(float *)malloc((m)*(n-1)*(sizeof(float)));
cout<<"请输入"<<m<<"行"<<n<<"列的增广矩阵:"<<endl;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
cin>>*(Matrix+i*n+j);
if(j!=n-1)
{
*(CoefficientMatrix+x)=*(Matrix+n*i+j);
x=x+1;
}
}
}
cout<<"增广矩阵:"<<endl;
printmat(Matrix,m,n);
cout<<endl;
cout<<"系数矩阵:"<<endl;
printmat(CoefficientMatrix,m,n-1);
cout<<endl;
for(j=0;j<n;j++) //求增广矩阵的行最简矩阵
{
CheckZeroOfEveryRow(Matrix,m,n);//统计每行从开头起所具有的数据为0的元素的个数并赋给数组ZeroOfRow
// cout<<"ZeroOfRow:"<<endl;
// printxxx(ZeroOfRow,m);
for(int h=0;h<m-1;h++) //依照连续0由少到多,对矩阵的行进行排序
{
min=(*(ZeroOfRow+h)),tag=h;
for(k=h+1;k<=m-1;k++)
if(min>(*(ZeroOfRow+k)))
{
min=(*(ZeroOfRow+k));
tag=k;
}
ExchangeRow(Matrix,m,n,h,tag);
// cout<<"j="<<j<<",h="<<h<<",k="<<k<<endl;
// printmat(Matrix,m,n);
}
CheckZeroOfEveryRow(Matrix,m,n); //行交换后重新统计每行从开头起所具有的数据为0的元素的个数并赋给数组ZerosOfRow
// cout<<"ZeroOfRow:"<<endl;
// printxxx(ZeroOfRow,m);
Judge(Matrix,m,n,j); //判定第j列的数据是否为0,并将1或0赋给IfZeroOfRow数组
// cout<<"IfZeroOfRow:"<<endl;
// printxxx(IfZeroOfRow,m);
for(k=0;k<m;k++) //如果本行前面的数据均为0即ZerosOfRow k ==j(或者该列为第首列)且本行该列的数据不为0,则将该进行行置1运算
if( (j==0||(*(ZeroOfRow+k))==j) && ((*(IfZeroOfRow+k))==1))
{
Multiply(Matrix,m,n,k,*(Matrix+n*k+j));
// cout<<"j="<<j<<",k="<<k<<endl;
// printmat(Matrix,m,n);
}
int label=-1; //用来label标记使得其他行变为0的辅助基本行的行号,该行前面的元素为0,该列上的元素为1
// cout<<"label="<<label<<endl;
for(k1=0;k1<m;k1++)
if((j==0||(*(ZeroOfRow+k1))==j)&&((*(IfZeroOfRow+k1))==1)) //如果本行前面的数据均为0即 ZerosOfRow k ==j(或者该列为第首列)且本行该列的数据不为0
{
label=k1;
break;
}
// cout<<"label="<<label<<endl;
// cout<<"k1="<<k1<<endl;
if(label!=-1)
{
for(int k2=0;k2<m;k2++)
if((k2!=label)&&((*(IfZeroOfRow+k2))==1))
{
Minus(Matrix,m,n,label,k2,*(Matrix+k2*n+j));
// cout<<"j="<<j<<",k1="<<k1<<",k2="<<k2<<",lablel="<<label<<",k="<<k<<endl;
// printmat(Matrix,m,n);
}
}
}
cout<<"原矩阵的最简行矩阵是:"<<endl;
printmat(Matrix,m,n);
cout<<endl;
r1=gfrank(Matrix,m,n);
r2=gfrank(CoefficientMatrix,m,n-1);
cout<<"增广矩阵的秩 = "<<r1<<" 系数矩阵的秩 = "<<r2<<endl;
//根据矩阵的秩判断解的情况
if(r2==r1)
{
if((r2==n-1)&&(r1==n-1))
{
cout<<"该线性方程组有唯一解"<<endl;
for(i=0;i<m;i++)
{
cout<<"X"<<i+1<<" = "<<(*(Matrix+i*n+n-1))<<endl;
}
}
else
if((r1==r2)&&(r1<n-1)&&(r2<n-1))
{
cout<<"线性方程组有通解"<<endl;
for(i=0;i<m;i++)
for(j=0;j<n-1;j++)
if(*(Matrix+n*i+j)==1)
{
cout<<"X"<<j+1<<" = "<<(*(Matrix+i*n+n-1));
for(k=j+1;k<n-1;k++)
if(*(Matrix+n*i+k)!=0)
{
t=((*(Matrix+i*n+n-1))/(*(Matrix+n*i+k)));
if(t<0)
if(t==-1)
cout<<"+X"<<k+1;
else
cout<<"+"<<-t<<"X"<<k+1;
else
if(t==1)
cout<<"-X"<<k+1;
else
cout<<"-"<<t<<"X"<<k+1;
}
cout<<endl;
break;
}
}
}
else
cout<<"该线性方程组无解"<<endl;
system("pause");
}
void Multiply(float *p,int m,int n,int k,float kj)
{
for(int j=0;j<n;j++)
(*(p+n*k+j))/=kj;
}
void printmat(float *p,int m,int n) //输出矩阵
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
cout<<setw(8)<<*(p+n*i+j);
}
cout<<endl;
}
cout<<endl;
}
void printxxx(int *p,int n)
{
for(int i=0;i<n;i++)
cout<<setw(8)<<*(p+i)<<" ";
cout<<endl;
}
void ExchangeRow(float *p,int m,int n,int h,int tag) //交换矩阵两行的元素
{
int j;float t;
for(j=0;j<n;j++)
{
t=*(p+h*n+j);
*(p+h*n+j)=*(p+tag*n+j);
*(p+tag*n+j)=t;
}
}
void CheckZeroOfEveryRow(float *a,int m,int n) //统计每行从开头起所具有的数据为0的元素的个数并赋给数组ZerosOfRow
{
int i,j;
for(i=0;i<m;i++)
{
int d=0;
for(j=0;j<m;j++)
if(fabs(*(a+n*i+j))<0.001)
{
d++;
*(ZeroOfRow+i)=d;
}
else
{
*(ZeroOfRow+i)=d;
break;
}
}
}
void Judge(float *p,int m,int n,int j) //判定某列的数据是否为0,并将1或0赋给数组IfZerosOfRow
{
int i;
for(i=0;i<m;i++)
if(fabs(*(p+n*i+j))<0.001)
*(IfZeroOfRow+i)=0;
else
*(IfZeroOfRow+i)=1;
}
void Minus(float *p,int m,int n,int a,int b,float Rb)//b行的数据减去a行的数据与b行该列数据的乘积,将所得的差值再依次赋给b行的数据
{
int j;
for(j=0;j<n;j++)
{
if(fabs((*(p+b*n+j))-(*(p+a*n+j))*Rb)<0.001)
(*(p+b*n+j))=0;
else
(*(p+b*n+j))=(*(p+b*n+j))-(*(p+a*n+j))*Rb;
}
}
int gfrank(float *p,int m,int n)
{
int i;
float t;
int ri,ci; //行标记与列标记
int f_z; //某列是否全为0的标志,为1表示全为0
for(ri=ci=0;ci<n;ci++)
{
f_z=1;
for(i=ri;i<m;i++)
if((*(p+i*n+ci))!=0)
{
if(i!=ri)
if(f_z)
ExchangeRow(p,m,n-ci,ri,i);
else
{
t=(*(p+i*n+ci));
mul_row((p+i*n+ci),*(p+ri*n+ci),n-ci);
add_row((p+i*n+ci),(p+ri*n+ci),-t,n-ci);
}
f_z=0;
}
if(!f_z)
ri++;
}
return ri;
}
void mul_row(float *a,float k,int n) //矩阵的一行做乘法运算
{
int i;
for(i=0;i<n;i++)
*(a+i)*=k;
}
void add_row(float *a1,float *a2,int k,int n)//矩阵的一行做加法运算
{
int i;
for(i=0;i<n;i++)
*(a1+i)+=(*(a2+i))*k;
}
- 1
- 2
前往页