求解方程组的实现
对于方程组,我们分为一元二次方程、一元二次方程、二元一次方程组和线性方程组来分析。下面为大致的划分思路:
一元一次方程
这是最简单的方程,例如a*x=b,利用C语言写出程序:(一元一次非常简单,Java也就不重复了)
C语言:
#include<stdio.h>
int main()
{
float a,b,x;
scanf("%f%f",&a,&b);
x= b/a;
printf("%f",x);
}
一元二次方程
一元二次方程的求解有多种方法,例如开方法、配方法、因式分解、求根公式等等,我们采用求根公式来进行求解:
求根公式如下:
所以,对于一元二次方程的求解,根据公式求即可。
C语言:
#include<stdio.h>
#include<math.h>
int main()
{
double a,b,c,disc,x1,x2;
char key;
while(1)
{
printf("一元二次方程为ax*x+bx+c=0,请输入a,b,c的值:\n");
scanf("%lf%lf%lf",&a,&b,&c);
disc=b*b-4*a*c;
if(disc == 0)
{
x1=-b/(2*a);
x2=x1;
printf("方程的两个实根为x1=x2=%lf\n",x1);
}
else if(disc < 0 )
printf("方程没有实数根。\n");
else
{
x1 = (-b + sqrt(disc))/(2*a);
x2 = (-b - sqrt(disc))/(2*a);
printf("方程两个实根为x1=%lf,x2=%lf\n",x1,x2);
}
printf("是否继续?是的话输入y,否输入n\n");
scanf("%s",&key);
if(key == 'y')
continue;
else if(key == 'n')
break;
else
{
printf("输入错误,关闭程序。\n");
break;
}
}
}
Java:
import java.util.Scanner;
public class Oo {
public static void main(String[] args) {
while(true)
{
Scanner in=new Scanner(System.in);
System.out.println("一元二次方程为ax*x+bx+c=0,请输入a,b,c的值:");
System.out.print("请输入a的值:");
double a = in.nextDouble();
System.out.print("请输入b的值:");
double b = in.nextDouble();
System.out.print("请输入c的值:");
double c = in.nextDouble();
double disc=b*b-4*a*c;
if(disc == 0)
{
double x1=-b/(2*a);
double x2=x1;
System.out.println("方程的两个实根为x1=x2="+x1);
}
else if(disc < 0 )
System.out.println("方程没有实数根。");
else
{
double x1 = (-b + Math.sqrt(disc))/(2*a);
double x2 = (-b - Math.sqrt(disc))/(2*a);
System.out.println("方程两个实根为x1="+x1+",x2="+x2);
}
System.out.println("是否继续?是的话输入1,否输入0");
int key = in.nextInt();
if(key == 1)
continue;
else if(key == 0)
break;
else
{
System.out.println("输入错误,关闭程序。");
break;
}
}
}
}
二元一次方程
1、问题描述:
给定一个二元一次方程组,形如:
a1 * x + b1 * y = c1;
a2 * x + b2 * y = c2;
求解x,y。
2、设计思路:
二元一次方程组是由两个含有两个未知数的方程组成的,要求解,就要把二元转化为一元。初中的时候我们学过,要用最大公约数完成消元的目的,
以下为详细思路过程,理解的人可以跳过:
a1 * a2为x的系数的最大公约数,将1式* a2,2式*a1来达成上下两式系数相同,然后1式-2式,消除x,解出y的值,同理解出x的值。(或者把y的值回代求得x的解。同理,也可以消去y先求x的值。)
3、实现
C语言:
#include<stdio.h>
int main()
{
int a1,b1,c1;
int a2,b2,c2;
int a3,b3,c3;
int a4,b4,c4;
int x,y;
printf("给定一个二元一次方程组,形如:\na1 * x + b1 * y = c1;\na2 * x + b2 * y = c2;\n");
printf("请输入a1,b1,c1,a2,b2,c2的值:\n");
scanf("%d%d%d%d%d%d",&a1,&b1,&c1,&a2,&b2,&c2);
a3 = a1*a2; a4 = a2*a1;
b3 = b1*a2; b4 = b2*a1;
c3 = c1*a2; c4 = c2*a1;
y = (c3-c4)/(b3-b4);
a3 = a1*b2; a4 = a2*b1;
b3 = b1*b2; b4 = b2*b1;
c3 = c1*b2; c4 = c2*b1;
x = (c3-c4)/(a3-a4);
printf("求得x和y的值为\nx= %d,y= %d\n",x,y);
return 0;
}
Java:
import java.util.Scanner;
public class To {
public static void main(String[] args) {
// TODO Auto-generated method stub
while(true) {
Scanner sc = new Scanner(System.in);
System.out.println("给定一个二元一次方程组,形如:");
System.out.println("a1 * x + b1 * y = c1;");
System.out.println("a2 * x + b2 * y = c2;");
System.out.println("请输入a1,b1,c1,a2,b2,c2的值:");
int a1 = sc.nextInt();
int b1 = sc.nextInt();
int c1 = sc.nextInt();
int a2 = sc.nextInt();
int b2 = sc.nextInt();
int c2 = sc.nextInt();
int y = (c2*a1 - a2*c1)/(a1*b2-a2*b1);
int x = (c1-b1*y)/a1;
System.out.println("解为 x="+x+" y="+y);
System.out.println("是否继续?是的话输入1,否输入0");
int key = sc.nextInt();
if(key == 1)
continue;
else if(key == 0)
break;
else
{
System.out.println("输入错误,关闭程序。");
break;
}
}
}
}
线性方程组
含有n个未知数的线性方程组称为n元线性方程组。
当其右端的常数项b1,b2,…,bn不全为零时,线性方程组称为非齐次线性方程组。当常数项全为零时,线性方程组称为齐次线性方程组.
系数构成的行列式称为该方程组的系数行列式D,即
当D≠0时,根据线性代数的克莱姆法则可知,线性方程组的解存在且唯一
直接法
如果所有运算都是精确进行的,那么经过有限步运算就可以求出方程组精确解的方法。
在实际计算过程中,由于舍入误差的存在和影响,直接法一般只能求得方程组的近似解。对于中等规模的线性方程组(n<200),由于直接法的准确性和可靠性高,一般都用直接法求解。
在直接法里,我们采用高斯消元法中的列主元消元法和Doolitle分解法来解决问题。
高斯消元法
高斯消元法的步骤:消元和回代。
列主元消去法的解题过程如下图,把每一列的最大值选出,将这一行与第一行交换,再把第一列的其他行化为0,再看除去第一行第一列的矩阵,重复上面步骤,直到将系数矩阵转换成上三角形式,
public class EquationSolver {
/**
* @列主元高斯消去法
*/
static double a[][];
static double b[];
static double x[];
static int n;
static int n2; //记录换行的次数
public static void Elimination() {
//消元
PrintA();
for (int k = 0; k < n; k++) {
Wrap(k);
for (int i = k + 1; i < n; i++) {
double l = a[i][k] / a[k][k];
a[i][k] = 0.0;
for (int j = k + 1; j < n; j++)
a[i][j] = a[i][j] - l * a[k][j];
b[i] = b[i] - l * b[k];
}
System.out.println("第" + k + "次消元后:");
PrintA();
}
}
public static void Back()//回代
{
x[n - 1] = b[n - 1] / a[n - 1][n - 1];
for (int i = n - 2; i >= 0; i--)
x[i] = (b[i] - jisuan(i)) / a[i][i];
}
public static double jisuan(int i) {
double he = 0.0;
for (int j = i; j <= n - 1