欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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;
            }

        }