C#程序计算N阶行列式的值及N元一次方程组
程序员文章站
2022-07-16 23:24:32
C#程序计算N阶行列式的值及N元一次方程组 用了挺长时间自行完成了C#程序计算N阶行列式的值及N元一次方程组。由于自己没有在网上查阅其他资料,所以只能硬着头皮用最朴素的思想和基础的算法进行编程。在给出代码之前,我先简单发表一些自己的粗鄙之见。。。 1.数学思想:有了线性代数中高斯提供的公式,我们很容 ......
c#程序计算n阶行列式的值及n元一次方程组
用了挺长时间自行完成了c#程序计算n阶行列式的值及n元一次方程组。由于自己没有在网上查阅其他资料,所以只能硬着头皮用最朴素的思想和基础的算法进行编程。在给出代码之前,我先简单发表一些自己的粗鄙之见。。。
1.数学思想:有了线性代数中高斯提供的公式,我们很容易就能得到n阶方程的解的统一计算方法:即xn=dn/d。其中d是系数矩阵的行列式值,dn是用每个方程的结果分别代替系数矩阵中的每列值,所得新的行列式的值。 那么我们的关键问题就是(1)如何计算一个n阶行列式的值(2)如何得到n个新的行列式。下面就对这两个关键问题进行探讨。
2.问题一:如何计算n阶行列式的值。我没有选用网上的一些诸如“加边法”等一些方法。选用了n阶行列式最基本的计算公式。即求任意一行或列的所有元素乘以他们的余子式,进行降阶,最后在二阶用主对角线之积减副对角线之积进行计算。朴素的思想有着“易理解,难操作或性能低”的特点。选用这种方法的本质就是:递归。
3.问题二:问题二相对问题一而言更好解决,对每列进行遍历,用方程值组代替列组,创建新的行列式放到问题一的函数中计算即可。
下面附上代码:
static void main() { bool tap = true; while (tap) { //输出标题并输入阶数 console.setcursorposition(48, 3); console.writeline("解n元一次方程组"); console.write("请输入n元方程组的阶数(未知数的个数):"); int n = convert.toint32(console.readline()); //依次输入每行方程的系数和结果 double[,] xishu = new double[n, n]; double[] zhi = new double[n]; double[] eachlineresult = new double[n]; console.writeline("请依次输入每行的系数数和结果数:"); console.writeline(); for (int i = 0; i < n; i++) { console.writeline("请输入第{0}行的系数值和结果值", i + 1); for (int j = 0; j < n; j++) { xishu[i, j] = convert.todouble(console.readline()); } console.writeline("请输入第{0}行的结果值", i + 1); zhi[i] = convert.todouble(console.readline()); } //计算行列式的值和用结果值代替系数的行列式的值 double result = hanglieshi(n, xishu); //测试用句1: console.writeline("计算出行列式的结果为:{0}", result); if (result == 0) console.writeline("此方程无解!");//行列式值为0,方程无解 else { for (int i = 0; i < n; i++) { double[,] tempxishu = new double[n, n]; for (int ii = 0; ii < n; ii++) { for (int jj = 0; jj < n; jj++) { tempxishu[ii, jj] = xishu[ii, jj]; } } eachlineresult[i] = rexishu(i, tempxishu, zhi, n); //测试用句2: console.writeline("第{0}个结果行列式的值为:{1}",i+1,eachlineresult[i]); } //输出每一个结果的值 console.writeline(); console.writeline("{0}元一次方程组的解集如下:", n); for (int i = 0; i < n; i++) { console.writeline("x{0}:{1}", i + 1, eachlineresult[i] / result); } } console.writeline(); console.writeline("你是否要继续计算?回答:是或不是"); string choice = console.readline(); while (choice != "是"&& choice != "不是") choice = console.readline(); if (choice == "是") { console.clear(); } else tap = false; } //计算行列式函数:利用递归和行列式的数学计算式计算。时间复杂度为o(n三次方),性能较低。 double hanglieshi (int n,double [,] xishu) { double mo = 0; if (n == 0) return 0; else if (n == 1) return xishu[0, 0]; else if (n == 2) return xishu[0, 0] * xishu[1, 1] - xishu[0,1] * xishu[1,0]; else { for (int i = 0; i < n; i++) { double[,] newxishu = new double[n - 1, n - 1]; for(int j = 0; j < n - 1; j++) { int mark = 0; for (int k = 0; k <n-1; k++) { if (k == i) { newxishu[j, k] = xishu[j + 1, mark + 1]; mark++; } else newxishu[j, k] = xishu[j + 1, mark]; //console.writeline("k的值为:{0}\tmark的值为:{1}\t数组的值为:{2}",k,mark,newxishu[j,k]); mark++; } } //console.writeline("这是第{0}次循环",i+1); if(i%2==0) mo += xishu[0,i]*hanglieshi(n - 1, newxishu); else mo -= xishu[0, i] * hanglieshi(n - 1, newxishu); } return mo; } } /*创建新的数组让方程结果值代替列值,时间复杂度为o(n)主要问题在空间复杂度上,传 参时,需要把原数组复制,所以要o(n三次方)。注意:正常函数传参是按值传参,函数内形参不 改变函数外部实参的值。但是数组比较特殊,会被更改。 */ double rexishu(int lieshu,double [,]xishu,double[]zhi,int size) { console.writeline(); for (int i = 0; i <size; i++) { xishu[i, lieshu] = zhi[i]; } double resulti=hanglieshi(size,xishu); return resulti; } }