给定一个 n 元一次方程组,求方程组的解。(java8)

问题:

输入

测试数据只有一组。

第一行为整数 n (1≤n≤26),表示方程组有 n 元,接下去 n 行为方程。

第 2 到 n+1 行为方程组。并且方程的格式按以下的格式规定:

  1. 方程中的变量为大写的字母 A-Z,也就是说,最多有 26 个变量。
  2. 方程中只有字母,整数,+ 号,- 号,= 号,没有多余的空格。
  3. 每个方程中至少有一个变量,相同的变量不会重复出现。
  4. 每个方程中有且只有一个 = 号,并且变量只会出现在等号的左边,常数只会出现在右边。

输出

如果方程有解 (有唯一解),则输出 n 行方程的解,格式为(结果按 A-Z 的顺序输出):

A=1.00
B=-1.00
C=3.12
…

中间不包含多余的空格,精确到 0.01(需要四舍五入)。

如果方程没有解,或者有不止一个的解,输出 No solution

样例

input

3
1A+2B+3D=4
+2A+4B+5D=3
B+3A+2D=1

output

A=-1.40
B=-4.80
D=5.00
package day1;

import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Pattern;

public class equation {

    //移除数组中为空的元素
    public static String[] removeArrayEmptyText(String[] strArray) {

        List<String> strList= Arrays.asList(strArray);
        List<String> strListNew=new ArrayList<>();

        for (int i = 0; i <strList.size(); i++) {
            if (strList.get(i)!=null&&!strList.get(i).equals("")){
                strListNew.add(strList.get(i));            }
        }
        String[] strNewArray = strListNew.toArray(new String[strListNew.size()]);
        return   strNewArray;
    }
    //四舍五入,不足保留数位时用0补全
    public static String roundByScale(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException(
                    "The   scale   must   be   a   positive   integer   or   zero");
        }
        if(scale == 0){
            return new DecimalFormat("0").format(v);
        }
        String formatStr = "0.";
        for(int i=0;i<scale;i++){
            formatStr = formatStr + "0";
        }
        return new DecimalFormat(formatStr).format(v);
    }



    //方程式转换为矩阵
    public static Double[][] strFormatMatrix(Double[][] matrix,String[] variables,String[] equations){

        HashMap<String,Double> dict=new HashMap<>();
        for (int i = 0; i <equations.length; i++) {
            //dict init
            for (int j = 0; j <variables.length ; j++) {
                dict.put(variables[j],Double.valueOf(0));
            }
            String[] var=removeArrayEmptyText(equations[i].split("\\W|[0-9]"));//变量
            String[] numbers=removeArrayEmptyText(equations[i].split("[A-Z]|="));//数值

            for (int j = 0; j <var.length ; j++) {

                Double number ;
                if(numbers[j].equals("+")){
                    number=Double.valueOf(1);
                }else if(numbers[j].equals("-")){
                    number=Double.valueOf(-1);
                }else {
                    number = Double.valueOf(numbers[j]);
                }
                dict.put(var[j],number);
            }

            for (int j = 0; j <variables.length ; j++) {
                matrix[i][j]=dict.get(variables[j]);
            }

            matrix[i][variables.length]=(Double.valueOf(numbers[numbers.length-1]));
        }
        return matrix;
    }

    //高斯消元法
    public static void gauss(Double[][] matrix,int numOfVar,String[] variables){
        ArrayList<Integer> ed=new ArrayList<>();
        for (int q = 0; q <numOfVar ; q++) {
            for (int i = 0; i < numOfVar; i++) {

                if (matrix[i][q] != 0&&ed.indexOf(i)==-1) {
                    ed.add(i);

                    for (int j = 0; j < numOfVar; j++) {

                        if (matrix[j][q] != 0&&j!=i) {
                            Double rate=matrix[j][q]/matrix[i][q];
                            for (int k = 0; k < numOfVar+1; k++) {
                                matrix[j][k]=matrix[j][k]-rate*matrix[i][k];
                            }
                        }
                    }
                    break;
                }


            }
        }


        //化为单位矩阵
        for (int i = 0; i <numOfVar ; i++) {
            for (int j = 0; j <numOfVar ; j++) {
                if (matrix[i][j]!=1 && matrix[i][j]!=0){
                    matrix[i][numOfVar]=matrix[i][numOfVar]/matrix[i][j];
                    matrix[i][j]=Double.valueOf(1);
                    break;
                }
            }

        }


        //判断是否有解
        int countOfY=0;
        for (int i = 0; i <numOfVar ; i++) {
            if(matrix[i][numOfVar]!=0){
                countOfY++;
            }
        }
        int countOfX=0;
        for (int i = 0; i <numOfVar ; i++) {
            for (int j = 0; j <numOfVar ; j++) {
                if (matrix[i][j]!=0){
                    countOfX++;
                    break;
                }
            }

        }


        if(countOfX==countOfY&&countOfX==numOfVar){
            for (int i = 0; i <numOfVar ; i++) {
                for (int j = 0; j <numOfVar ; j++) {
                    if (matrix[j][i]!=0){
                        System.out.println(variables[i]+"="+roundByScale(matrix[j][numOfVar],2)) ;
                        break;
                    }
                }
            }
        }else {
            System.out.println("No solution");
        }
    }



    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int num=Integer.parseInt(sc.nextLine());
        Double[][] matrix=new Double[num][num+1];
        String[] var=new String[num];
        String[] equs=new String[num];
        for (int i = 0; i <var.length ; i++) {
            var[i]="Null";
        }

        for (int i = 0; i < num; i++) {
            String equ=sc.nextLine();
            if(!Pattern.matches("\\W",String.valueOf(equ.charAt(0)))){
                equ='+'+equ;
            }
            equs[i]=equ;
        }
        sc.close();
        int count=0;
        for (int i = 0; i <equs.length ; i++) {
            String[] current=removeArrayEmptyText(equs[i].split("\\W|[0-9]"));
            for (int j = 0; j <current.length ; j++) {
                if(Arrays.binarySearch(var,current[j])<0){
                    var[count]=current[j];
                    count++;
                    if(count==num){
                        break;
                    }
                }
            }
            Arrays.sort(var);

        }

        strFormatMatrix(matrix,var,equs);

        gauss(matrix,num,var);


    }
}

 

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值