如何从左到右计算表达式

3
我正在创建一个数学问答游戏,向用户输出随机的算术问题。我有一个函数,它创建问题并将它们存储在字符串数组中。问题中包含整数的数量可以不同,例如:一个问题可以是3+4-9/3=或4*2/9=,但必须至少有两个整数,例如:3+4=等。
我的目标是从左到右读取问题并忽略运算次序进行计算。例如:4+2*5=应该等于30而不是14。
我的思路如下:
获取一个问题,循环遍历字符串并提取单个字符并将它们存储在ArrayList中。将这些字符转换为int类型,并首先计算数组列表中的前三个元素,将答案存储在临时int值中。获取接下来的两个元素并检查是否不包含等号,如果不包含,则使用这两个元素计算临时int值。当找到等号时继续执行此操作。如果找到等号,则停止迭代并产生结果。
我的问题是我似乎无法将操作符+,-,*,/转换为int值。我认为每个字符都可以转换为int。
public void initAnswers(){
   for(int i =0; i < questions.length; i++){
       ArrayList<Integer> indivialIntegers = new ArrayList<>();
       String questionToGetIndividual = questions[0];
       //extracting individual chars
       for(int j = 0; j < questionToGetIndividual.length(); j++){
           indivialIntegers.add(Character.getNumericValue(questionToGetIndividual.charAt(j)));
       }
   }

编辑 = 这是我的更新代码。我遇到了数字格式异常错误。 Caused by: java.lang.NumberFormatException: Invalid int

有人能看出为什么吗?顺便说一下,我编写了一个生成问题的方法(问题中整数的数量是随机生成的)。它们存储在数组中。我只是简单地迭代每个问题并评估答案:我的起始函数是initAnswers()。

public int computeAnswerThreeTerms(int numberOne, int numberTwo, String operation){
   if(operation.equals("+")){
       Log.d("onc","in addition");
       return numberOne + numberTwo;
   }else if(operation.equals("-")){
       Log.d("onc","in subtraction");
       return numberOne - numberTwo;
   }else if(operation.equals("/")){
       Log.d("onc","in division");
       return numberOne / numberTwo;
   }else if(operation.equals("*")){
       Log.d("onc","in multiplication");
       return numberOne * numberTwo;
   }else{
       return 0;
   }
}

public int computeAnswer(int numberOne, String operation, int runningTotal){

    if(operation.equals("+")){
        Log.d("onc","in addition");
        return numberOne + runningTotal;
    }else if(operation.equals("-")){
        Log.d("onc","in subtraction");
        return numberOne - runningTotal;
    }else if(operation.equals("/")){
        Log.d("onc","in division");
        return numberOne / runningTotal;
    }else if(operation.equals("*")){
        Log.d("onc","in multiplication");
        return numberOne * runningTotal;
    }else{
        return 0;
    }
}

public void getAnswer(ArrayList<String> toBeExamined){
    //get numbers and put them in an array
    //get operations and put them in an array
    for(int i =0; i < toBeExamined.size(); i++){
        String extractingIntegers = toBeExamined.get(i);
        // /d matches digits /D matches non digits
        String[] numbersInStringformat = extractingIntegers.split("/d");
        ArrayList<Integer> numbersInNumberformat = new ArrayList<>();
        for(int counter = 0; counter < numbersInStringformat.length; counter++){
            numbersInNumberformat.add(Integer.parseInt(numbersInStringformat[counter]));
        }
        String[] operationsInStringformat = extractingIntegers.split("/D");

        int tempAnswer;
        int tempIntCounter =0;
        int stringCounter =0;
        tempAnswer = computeAnswerThreeTerms(numbersInNumberformat.get(tempIntCounter), numbersInNumberformat.get(tempIntCounter+1), operationsInStringformat[stringCounter]);
        tempIntCounter = 1;
        while(!operationsInStringformat[1].equals("=")){
            if(operationsInStringformat[stringCounter].equals("=")){
                break;
            }
            tempAnswer = computeAnswer(numbersInNumberformat.get(tempIntCounter++),operationsInStringformat[stringCounter],tempAnswer);
        }
        answers[i] = tempAnswer;

    }
}

public void initAnswers(){
    ArrayList<String> individualCharacters = new ArrayList<>();

    for(int i =0; i < questions.length; i++){
        //change i to 0 for testing purposes
       String questionToGetIndividual = questions[i];
       //extracting individual chars
       individualCharacters.add(questionToGetIndividual);
    }
    getAnswer(individualCharacters);
}

1
如果你不考虑运算顺序,为什么不从左到右逐个字符读取字符串,直到遇到非数字字符,那就是你的第一个数字,依此类推。 - Ariel Pinchover
@Infested 但是我怎么知道我需要加、乘、减去那个数字等等呢? - Tarikh Chouhan
你可以阅读并检查每个字符,如果不是数字,则是四种数学运算之一。 - ΦXocę 웃 Пepeúpa ツ
你可以将该操作保存为字符串,当你获得第二个数字时使用 switch case。 - Ariel Pinchover
2
你为什么想要错误地这样做呢?为什么不像其他人一样使用递归下降表达式解析器或Dijkstra Shunting-yard算法呢? - user207421
2个回答

0

给你

String question = "11+2*3=";
        int first = Integer.MAX_VALUE;
        int second = 0;
        int result = 0;
        boolean firstNumber = true;
        String operator = "";
        String number = "";

    for(char c : question.toCharArray()) {
        if(c != '+' && c != '-' && c != '*' && c != '/' && c != '=') {
            number += c;
        } else {
            if(firstNumber) {
                first = Integer.parseInt(number);
                firstNumber = false;
                operator += c;
                number = "";
                result = first;
            } else {
                second = Integer.parseInt(number);
                //firstNumber = true;
                switch(operator) {
                case "+":
                    result = result + second;
                    break;
                case "-":
                    result = result - second;
                    break;
                case "*":
                    result = result * second;
                    break;
                case "/":
                    result = result / second;
                    break;
                }
                number = "";
                operator = "";
                operator += c;
                if(operator.equals("=")) {
                    System.out.println(result);
                    return;
                }
            }
        }
    }

0

你需要做的基本上是:

  • 从你的问题中解析出操作数的int[](假设有n个项目);
  • 解析运算符的Operator[](+-/*)。它将有n-1个项目。Operator是一个简单的enum,具有从char到值的转换器和将Operator应用于2个操作数的函数;
  • 循环遍历运算符数组,将其应用于当前值和操作数;

此外,请查看这个问题:Java中解析数学表达式的好库是什么?


如果int是双位数,比如33,那么它将填充两个索引而不是一个索引。 - Tarikh Chouhan
@TarikhChouhan - 只需为其编写一个适当的解析器即可。例如,您可以通过“+-/*”字符拆分字符串并将所有子字符串转换为整数。 - Konstantin Loginov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接