Java 表达式求解器算法

问题描述 投票:0回答:3

我正在尝试创建一个程序,它将表达式作为字符串接收并解决它。因此,如果输入是 3 + 5,它将返回 8。我已经完成了大部分编码,但我不确定为什么我在 Java 中不断收到 UnsupportedOperationExpression。如果可以的话请帮忙!

** 另外,我必须在这个作业中使用 ArrayLists,因为我还没有学习列表。这是到目前为止我当前的代码:

    import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;

public class FirstPart {
   public static void main(String[] args) {
      String sampleString = "1 + 2 + 3 / 2 + 1";
      String[] items = sampleString.split(" ");
      List<String> itemList = Arrays.asList(items);
      System.out.println(itemList);
      for(int zz=0; zz<itemList.size(); zz++)
        if(itemList.get(zz).equals("*"))
           {itemList.set(zz-1,Integer.toString((Integer.parseInt(itemList.get(zz-1))*Integer.parseInt(itemList.get(zz+1)))));
           itemList.remove(zz+1);
           itemList.remove(zz);
           zz--;}
        else if(itemList.get(zz).equals("/"))
           {itemList.set(zz-1,Integer.toString((Integer.parseInt(itemList.get(zz-1))/Integer.parseInt(itemList.get(zz+1)))));
           itemList.remove(zz+1);
           itemList.remove(zz);
           zz--;}
      for(int zz=0; zz<itemList.size(); zz++)
        if(itemList.get(zz).equals("+"))
           {itemList.set(zz-1,Integer.toString((Integer.parseInt(itemList.get(zz-1))+Integer.parseInt(itemList.get(zz+1)))));
           itemList.remove(zz+1);
           itemList.remove(zz);
           zz--;}
        else if(itemList.get(zz).equals("-"))
           {itemList.set(zz-1,Integer.toString((Integer.parseInt(itemList.get(zz-1))+Integer.parseInt(itemList.get(zz+1)))));
           itemList.remove(zz+1);
           itemList.remove(zz);
           zz--;}
      System.out.println(itemList);
   }
   }

如果您能提供帮助,再次感谢!

java expression solver
3个回答
2
投票

如果你从这样的数组构造一个

List

List<String> itemList = Arrays.asList(items)

返回的列表不允许从列表中删除项目

itemList.remove(zz + 1); // throws java.lang.UnsupportedOperationException

相反,创建一个支持删除的空列表并将所有数组元素添加到其中:

List<String> itemList = new java.util.ArrayList<>();
java.util.Collections.addAll(itemList, items);

0
投票

尝试阅读有关反向波兰表示法算法的内容。它似乎完全符合您的需要,您只需实施它即可。

https://en.wikipedia.org/wiki/Reverse_Polish_notation


0
投票

请参阅我的 java 程序原件,作者为 Rishi shakya 第 10 课。一个非常强大的表达式求解器可以在 BODMAS 中轻松执行 DMAS。 // 原创

import java.util.Scanner;
import java.util.ArrayList;
public class Calculator {
    private String arithmeticExpression;
    private ArrayList<Double> numberList = new ArrayList<>();
    private ArrayList<Character> operatorList = new ArrayList<>();

    public Calculator(String ArithmeticExpression) {
        this.arithmeticExpression = '+' + ArithmeticExpression;
    }

    private static String getArithmeticExpression() {
        Scanner in = new Scanner(System.in);
        System.out.println("Enter Your ArithmeticExpression");
        return in.nextLine();
    }

    private double evaluate(double operand1, double operand2, char operator) {
        double result = 0;
        switch (operator) {
            case '+' -> result = operand1 + operand2;
            case '-' -> result = operand1 - operand2;
            case '*' -> result = operand1 * operand2;
            case '/' -> result = operand1 / operand2;
        }
        return result;
    }

    private void getNumbers() {
        String[] Numbers = this.arithmeticExpression.split("[+\\-*/]");
        for (String Number : Numbers) {
            try {
                numberList.add(Double.parseDouble(Number));
            } catch (NumberFormatException ignored) {
            }
        }
    }

    private void simplifyAdditionSubtractionOperators() {
        StringBuilder simplifiedArithmeticExpression = new StringBuilder();
        String operator = "";
        int lowerBound, upperBound, flowControl = 0, numberCounter = 0;
        char finalOperator, Character;
        for (int counter = 0; counter < this.arithmeticExpression.length(); counter++) {
            Character = this.arithmeticExpression.charAt(counter);
            finalOperator = Character;
            if (Character == '-' || Character == '+') {
                lowerBound = counter;
                for (upperBound = lowerBound + 1; upperBound < this.arithmeticExpression.length() &&
                        (this.arithmeticExpression.charAt(upperBound) == '+' || this.arithmeticExpression.charAt(upperBound) == '-'); upperBound++) {
                    if (this.arithmeticExpression.charAt(upperBound - 1) == '+' || this.arithmeticExpression.charAt(upperBound - 1) == '-')
                        if (finalOperator == this.arithmeticExpression.charAt(upperBound))
                            finalOperator = '+';
                        else finalOperator = '-';
                }
                counter = upperBound - 1;
            }
            if (Character == '-' || Character == '+' || Character == '*' || Character == '/') {
                flowControl = 1;
                operator = String.valueOf(finalOperator);
            }
            if (operator.equals("-"))
                operator = "+-";
            if (flowControl == 1) {
                simplifiedArithmeticExpression.append(operator);
                flowControl = 2;
            } else if (flowControl == 2) {
                simplifiedArithmeticExpression.append(numberList.get(numberCounter));
                numberCounter++;
                flowControl = 0;
            }
        }
        this.arithmeticExpression = simplifiedArithmeticExpression.toString();
    }

    private void simplifyMultiplicationDivisionOperators() {
        char finalOperator, character;
        ArrayList<Character> simplifiedOperatorList = new ArrayList<>();
        for (int counter = 0; counter < this.arithmeticExpression.length(); counter++) {
            character = this.arithmeticExpression.charAt(counter);
            finalOperator = character;
            if (character == '/' || character == '*')
                if (this.arithmeticExpression.charAt(counter + 1) == '+')
                    counter++;
            if (character == '-' || character == '+' || character == '*' || character == '/')
                simplifiedOperatorList.add(finalOperator);
        }
        operatorList = simplifiedOperatorList;
    }

    private void evaluateMultiplicationDivision() {
        char operator;
        double result;
        while (operatorList.contains('*') || operatorList.contains('/'))
            for (int i = 1; i < operatorList.size(); i++) {
                operator = operatorList.get(i);
                if (operator == '*' || operator == '/') {
                    result = evaluate(numberList.get(i - 1), numberList.get(i), operator);
                    operatorList.remove(i);
                    numberList.remove(i);
                    numberList.add(i, result);
                    numberList.remove(i - 1);
                }
                roundAllNumbers(5);
            }
    }

    private void evaluateAdditionSubtraction() {
        double sum = 0;
        roundAllNumbers(5);
        for (double number : numberList)
            sum += number;
        numberList.clear();
        numberList.add(sum);
        roundAllNumbers(5);
    }

    private void getActualNumbers() {
        numberList.clear();
        String[] Numbers = this.arithmeticExpression.split("[+*/]");
        for (String Number : Numbers) {
            try {
                numberList.add(Double.parseDouble(Number));
            } catch (NumberFormatException ignored) {
            }
        }
    }

    private void updateArithmeticExpression() {
        StringBuilder ArithmeticExpression = new StringBuilder();
        String operator;
        double operand;
        for (int i = 0; i < numberList.size(); i++) {
            operator = Character.toString(operatorList.get(i));
            operand = numberList.get(i);
            ArithmeticExpression.append(operator).append(operand);
        }
        this.arithmeticExpression = ArithmeticExpression.toString();
    }

    private void roundAllNumbers(int n) {
        ArrayList<Double> roundedNumberList = new ArrayList<>();
        double number;
        for (double numberToRound : numberList) {
            number = numberToRound * Math.pow(10, n);
            number = Math.round(number);
            number = number / Math.pow(10, n);
            roundedNumberList.add(number);
        }
        numberList = roundedNumberList;
    }

    private void simplifyArithmeticExpression() {
        getNumbers();
        simplifyAdditionSubtractionOperators();
        simplifyMultiplicationDivisionOperators();
        getActualNumbers();
        operatorList.removeIf(operator -> operator == '-');
        updateArithmeticExpression();
        roundAllNumbers(5);
    }

    public double evaluate() throws SyntaxException,MathException {
        double result ;
        try {
                simplifyArithmeticExpression();
                evaluateMultiplicationDivision();
                evaluateAdditionSubtraction();
                result = numberList.get(0);
        } catch (IndexOutOfBoundsException e) {
            this.arithmeticExpression = "Syntax Error";
            throw new SyntaxException();
        }
        finally {
                 chackForMathException();
        }
        return result;
    }

    public static void main(String[] args) {
        String ArithmeticExpression;
        double result;
        while (true) {
            ArithmeticExpression = getArithmeticExpression();
            if (ArithmeticExpression.equalsIgnoreCase("EXIT"))
                break;
            Calculator Calculator = new Calculator(ArithmeticExpression);
                    try {
                        try {
                            result = Calculator.evaluate();
                            System.out.println(" Answer = " + result);
                        }catch (MathException e){
                            System.out.println(e.getMessage());
                        }
                    } catch (SyntaxException e) {
                        System.out.println(e.getMessage());
                    }
        }
    }
    private void chackForMathException() throws MathException{
        double limit = 9.999999999999E12;
        for(double devialValue : numberList)
            if(!(devialValue<=limit)){
               throw new MathException();
            }
    }
    static class MathException extends Throwable{
        public MathException(){}
        @Override
        public String getMessage() {
            return "Math Error : Can't perform operation";
        }
    }
    static class SyntaxException extends Throwable {
        public SyntaxException() {}
        @Override
        public String getMessage() {
           return "Syntax Error !";
        }
    }
}    
© www.soinside.com 2019 - 2024. All rights reserved.