一、运行结果展示:
二、关键词:C语言,解n元线性方程组,用行列式法
三、摘要:本文阐述了用C语言编程,通过求n阶行列式的值,解n元线性方程组的方法,并特别把程序附在后面。
四、解法:
解n元线性方程组:
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到n.
- 解法根据(克莱姆法则):把系数行列式的值记作d,把系数行列式的第j列换成常数项后所得行列式的值记作dj,如果系数行列式的值d≠0,则行列式有唯一解xj=dj/d,(其中j从1到n)
- 解法的关键:一是怎么编写求n阶行列式值的函数;二是怎么用常数项列换掉方程组中某一未知数的系数列;三是怎么保证函数调用后原系数行列式不变。
- 解法步骤:
1)求n阶行列式的值:要用到的性质有三条:a.当行列式主对角线的右上角(或左下角)元素全为0时,该行列式的值等于其主对角线元素的乘积。b.给行列式的某一列(或行)元素都乘以常数k,加到另一列(或行)的对应元素上,行列式的值不变。c.交换行列式的任意两列(或两行),行列式的值变号。
现设主对角线上某一元素aii≠0(如果aii=0,则需要在同一行aii的右边找一个不为0的元素,把这一列与aii所在列进行交换),它右边的元素为aij,则得权重因子q=-aij/aii,只要给第i列的每个元素分别乘以q,加到第j列对应元素上,就可以使aij变成0,且不会改变行列式的值。用此方法就能把本行aii右边的每一个aij(j从i 1到n)都变成0。
从a11开始重复进行以上操作,就能把每一个aii右边的所有元素全变成0,也就是把主对角线右上角的元素全变成了0.
再求出主对角线元素的积,也就求出了行列式的值。
2)编写换列函数:每次都要把原系数行列式数组a传递进换列函数,再把传进来的数组a复制一个副本数组f,然后把这个副本f中的第j列换成常数项,最后调用行列式求值函数求换列后行列式的值dj。
3)在求行列式值时,为了保证原系数行列式保持不变,始终要用副本行列式进行计算。
五、C语言用行列式解n元线性方程组程序如下:
//用行列式解n元线性方程组
#include <stdio.h>
#define N 30 //常数N应大于方程组的元数n
int main()
{ int i,j,k,n,h; //方程组的元数n,需要换的列h
double hlshi(double[N][N],int); //求行列式值函数原型声明
double huanlie(double[N][N],double[N],int,int);//行列式换列函数原型声明
double a[N][N]={},f[N][N]={},b[N]={},x0,xj; //系数行列式a,换列行列式f,常数项行列式b;系数行列式的值x0,其它行列式的值xj
printf("请输入方程组的元数n及n个常数项(相互用空格隔开):"); printf("n b[1] b[2] …b[n]:");
scanf("%d",&n); //读入方程的元数n
for(i=1;i<=n;i ) { scanf("%lf",&b[i]);} //读入每个常数项
printf("请输入未知数的n*n个系数(相互用空格隔开):\n");
for(i=1;i<=n;i )
{ for(j=1;j<=n;j )
{ scanf("%lf",&a[i][j]); //读入系数
f[i][j]=a[i][j]; //复制系数行列式
}
}
x0=hlshi(f,n); //调用函数求系数行列式的值x0,其中f,n为实参
if(x0!=0)
{ printf("此方程组的解为:\n");
for(h=1;h<=n;h ) //用常数项替换各列:
{ xj=huanlie(a,b,n,h); //调用函数,求换列后各行列式的值xj:
printf("x%d=%e\n",h,xj/x0); //输出方程组的解
}
}
else printf("此方程组无解或有无数解.\n");
}
//行列式换列函数:
double huanlie(double a[N][N],double b[N],int n,int h) //换列函数首部行,这里a,b,n,h为形参
{ double f[N][N];
int i,j,k;
for(i=1;i<=n;i ) //把a行列式复制到f行列式:
{ for(j=1;j<=n;j ) { f[i][j]=a[i][j];}
}
for(i=1;i<=n;i ) { f[i][h]=b[i];} //把第h列换成常数项:
double hlshi(double [N][N],int); //求行列式值函数原型声明
double xj;
xj=hlshi(f,n); //调用函数求h列换成常数项后各行列式的值xj
return (xj); //返回换列后行列式的值xj
}
//求行列式值的函数:
double hlshi(double f[N][N],int n) //函数首部行,这里f,n为形式参数
{ int i,j,k,m=1;
double q,t,x;
for(i=1;i<=n;i )
{ j=i; //主对角线元素行列标号相同
while(f[i][i]==0&&j<n) //若f[i][i]=0,则与后列交换:
{ j ;m=-m; //换列1次值取反
for(k=1;k<=n;k ) { t=f[k][i];f[k][i]=f[k][j];f[k][j]=t;}//交换i,j两列
}
for(j=i 1;j<=n;j ) //使行列式的右上三角形全为0:
{ if(f[i][j]==0) continue; //已经是0的继续下一个
q=-f[i][j]/f[i][i]; //求权重因子q=-j(列)/i(列)
for(k=i;k<=n;k ) { f[k][j] =f[k][i]*q;} //使f[i][i]右边各项全为0
}
}
x=f[1][1]*m; //确定首项正负
for(i=2;i<=n;i ) { x*=f[i][i];} //求主对角线之积
return (x); //返回行列式的值
}
,