如何计算数学表达式的值并检查用户答案?

时间:2017-02-15 21:58:02

标签: java android

非常感谢任何帮助或建议。我正在做一个简单的游戏,它产生十个不同的随机问题。问题可以由2个,3个或4个整数组成。例如:SQL Injection552 − 4 − 101102 / 3 / 3589 − 281

问题将显示在textview中,然后用户可以猜测,在编辑文本中输入值,然后单击自定义键盘上的键,它将检查答案,然后显示下一个问题,直到它达到10个问题。我有一个问题,从我的代码输入答案。无论我在这里做什么,我都无法输入随机生成的表达式的答案。

123 + 56 + 2

1 个答案:

答案 0 :(得分:2)

main()正在打印question,阅读用户的回答,然后将答案与q.getValue()进行比较。 q是一个与question无关且始终具有值0的问题元素。所以诀窍是回答0无论问题是什么,然后程序将打印CORRECT。 : - )

我在代码中找不到计算数学表达式正确值的任何地方。这可能是检查用户是否确实输入了正确结果的良好的第一步。

如果我们坚持将运算符优先权考虑在内,那么计算正确的结果并不是一件容易的事。 4 + 3 * 2应为10(而不是14)。我相信关于the Shunting-yard algorithm的阅读应该会让你有所帮助。这是解析数学表达式的算法,这只是计算其值的第一步,但仍然是第一步。

我建议面向对象的方法是Question对象知道如何检查答案。这是算法的一种实现,简化为四个运算符,但扩展到实际进行计算:

public boolean checkAnswer(int answer) {
    // calculate correct answer
    // use shunting yard algorithm
    Deque<Integer> outputQueue = new ArrayDeque<>();
    Deque<Operator> operatorStack = new ArrayDeque<>();
    for (QuestionElement element : questionElements) {
        outputQueue.push(element.getValue());
        Operator op = element.getOperator();
        if (op != null) {
            while (!operatorStack.isEmpty() && op.getPrecedence() <= operatorStack.peek().getPrecedence()) {
                int operand2 = outputQueue.pop();
                int operand1 = outputQueue.pop();
                outputQueue.push(operatorStack.pop().apply(operand1, operand2));
            }
            operatorStack.push(op);
        }
    }
    while (!operatorStack.isEmpty()) {
        int operand2 = outputQueue.pop();
        int operand1 = outputQueue.pop();
        outputQueue.push(operatorStack.pop().apply(operand1, operand2));
    }
    int result = outputQueue.pop();
    assert outputQueue.isEmpty();

    return answer == result;
}

您注意到我对Operator枚举也提出了一些新的要求。它有一个优先权。并且+运算符必须知道如何添加(通过其apply方法),对于其他运算符也是如此:

PLUS("+", 1) {
    @Override
    public int apply(int operand1, int operand2) {
        return operand1 + operand2;
    }
}, 
// etc.

public abstract int apply(int operand1, int operand2);

等等。 1是优先权; */具有更高的优先级,例如2。

现在在main()你只需要写:

        if (question.checkAnswer(answer)) {

如果您决定向用户解释应用严格的从左到右的评估,那么它会变得更简单:

public boolean checkAnswer(int answer) {
    // calculate correct answer
    // do left to right calculation
    int result = questionElements.get(0).getValue();
    for (int elementIndex = 1; elementIndex < questionElements.size(); elementIndex++) {
        Operator op = questionElements.get(elementIndex - 1).getOperator();
        result = op.apply(result, questionElements.get(elementIndex).getValue());
    }

    return answer == result;
}

运算符仍然需要apply方法,但它们不再需要优先级。