一、关键词:消元法,解任意线性方程组,C语言,用二维数组
二、摘要:本文阐述了只用二维数组通过逐步消元,解任意线性方程组的方法,并特别把用C语言编写的程序附在后面。
三、解法:
解任意方程组:
a11*x1+a12*x2+……a1n*xn=b1
a21*x1+a22*x2+……a2n*xn=b2
…………
an1*x1+an2*x2+……ann*xn=bn
为便于叙述把其中的某一方程记为:ai1*x1+ai2*x2+……ain*xn=bi,其中i属于自然数,且1<=i<=n.
前文讲的解系数为i^(n-j)形式的线性方程组,因为其末项系数始终相等,所以直接用下一个方程减去上一个方程,就能消掉末项未知数。但是对于任意系数的线性方程组该怎么消元呢?这里采取始终用第一个方程消掉其它方程末项未知数的方法, 并且需要引入一个权重系数q=-ain/a1n,因为ain+(-a1n*ain/a1n)=ain-ain=0.所以给第一个方程的每一项都乘以q,加到第i个方程的对应项,就能消掉末项未知数。
遇到第一个方程的未知数的系数是0时怎么办呢?每次消元前先找出末项系数不是0的方程,把它换到首行,然后用首行方程分别去消掉其它方程的末项;
如被消元的方程末项系数本身是0时,直接把这个方程作为消元后的新方程即可。
四、用C语言编程如下:
//二维数组消元法解n元1次方程组带过程
//方程形式为:a[i1]*x1+a[i2]*x2+…a[in]*xn=bi
//特色:用数组的大号行存储消元后的新方程,用"剩余行"(小号行)保存消元前的方程
#include <;
#include <ma;
#define N 30 //数组尺寸N应不小于方程元数n
int main ()
{ int k,i,j,n,m,s,h; //循环变量:k,i,j;元数(方程个数)n,末项标记m,首行标记s,行标记h
double a[N][N]={},b[N]={},x[N]={},q; //定义数组:系数a,常数项b,解x,消元权重q
printf("请输入方程组的元数n及n个常数项:n b[1] b[2] …b[n]]:");
scanf("%d",&n); //读入方程个数n
for(i=1;i<=n;i++) { scanf("%lf",&b[i]); } //读入各常数项b[i]
printf("请输入未知数的n*n个系数(用空格隔开):\n");
for(i=1;i<=n;i++)
{ for(j=1;j<=n;j++)
{ scanf("%lf",&a[i][j]); //读入系数
}
}
printf("所解方程组为:\n");
for(i=1;i<=n;i++) //输出原方程组:
{ printf(" %.0fx%d",a[i][1],1); //输出各未知数项首项
for(j=2;j<=n;j++) {printf(" %+-.0fx%d",a[i][j],j);} //输出其余未知数项
printf("=%.0f\n",b[i]); //输出常数项并换行
}
//逐步消元:
for(k=2;k<=n;k++) //组数(消元遍数)k
{ printf("消掉末项未知数得:\n");
s=k-1;m=n+2-k; //上组首行s,末项系数m
if(a[s][m]==0) //如上组首行末项系数=0,则:
{ h=s; //上组首行s复制到行标记h
while(a[h][m]==0&&h<n) {h++;} //找出上组末项系数不为0的行,并标记为h
for(j=1;j<=m;j++)
{ a[0][j]=a[s][j]; a[s][j]=a[h][j]; a[h][j]=a[0][j]; //交换h行与首行(k-1)的系数
}
b[0]=b[s]; b[s]=b[h]; b[h]=b[0]; //交换两行常数项
}
for(i=n-k;i>=0;i--) //行数i
{ h=n-i; //本行h,末项m
if(a[h][m]==0) //本行末项=0,直接输出该行:
{ printf(" %.1fx%d",a[h][1],1); //输出未知数项的首项
for(j=2;j<=m-1;j++) printf("%+-.1fx%d",a[h][j],j); //输出其余未知数项
}
else //本行末项!=0,用首行去消掉该行
{ q=-a[h][m]/a[s][m]; //q=h/(k-1),(q=本/首=本行末项系数除以首行末项系数)
a[h][1]+=a[s][1]*q;
printf(" %.1fx%d",a[h][1],1); //输出未知数项的首项
for(j=2;j<=m-1;j++) //求消掉末项未知数后的每一项系数(j为项数)
{ a[h][j]+=a[s][j]*q; //本=本-首*本/首(因对末项:本-首*本/首=0)
printf("%+-.1fx%d",a[h][j],j); //输出其余未知数项
}
b[h]+=b[s]*q; //求常数项
}
printf("=%.1f\n",b[h]);//输出常数项并换行
}
}
x[1]=b[n]/a[n][1]; //求x[1]
printf("此方程组的解为:\n x[1]=%.3e",x[1]); //输出x[1]
//倒过来把解代入各保留方程求其它未知数:
for(k=n-1;k>=1;k--) //求x[2]到x[n]:
{ m=n+1-k;
for(j=1;j<=n-k;j++) { b[k]-=a[k][j]*x[j]; } //把每个解代入并求差
x[m]=b[k]/a[k][m]; //求x[n]
printf("\n x[%d]=%.3e",m,x[m]); //输出x[n]
}
return 0;
}