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



任何帮助或建议将不胜感激。我正在做一个简单的游戏,该游戏会产生十个不同的随机问题。这些问题可以由2、3或4个整数组成。类似的东西:552 − 4 − 101102 / 3 / 3589 − 281123 + 56 + 2

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

public enum Operator {
PLUS("+"), MINUS("-"), MULTIPLIER("*"), DIVIDER("/");
private String displayValue;
private Operator(String displayValue) {
    this.displayValue = displayValue;
}
public String getDisplayValue() {
    return displayValue;
}}


public class Question{
 private List<QuestionElement> questionElements;
public Question(int sizeOfQuestionElemets) {
    questionElements = new ArrayList<QuestionElement>(sizeOfQuestionElemets);
}

public void addElement(QuestionElement questionElement) {
    questionElements.add(questionElement);
}
public List<QuestionElement> getElements() {
    return questionElements;
}
public int size() {
    return questionElements.size();
}
@Override
public String toString() {
    StringBuilder sb = new StringBuilder();
    for (QuestionElement questionElement : questionElements) {
        sb.append(questionElement);
    }
    return sb.toString().trim();
}
 }
public class QuestionElement {
private int value;
private Operator operator;
public int getValue() {
    return value;
}
public void setValue(int value) {
    this.value = value;
}
public Operator getOperator() {
    return operator;
}
public void setOperator(Operator operator) {
    this.operator = operator;
}
@Override
public String toString() {
    return value + (operator == null ? "" : " " + operator.getDisplayValue()) + " ";
}
 }
public class RandomQuestions {

static QuestionElement q =  new QuestionElement();
private static final int NUMBER_OF_QUESTIONS = 10;
private static final int MIN_QUESTION_ELEMENTS = 2;
private static final int MAX_QUESTION_ELEMENTS = 2;
private static final int MIN_QUESTION_ELEMENT_VALUE = 1;
private static final int MAX_QUESTION_ELEMENT_VALUE = 20;
private final Random randomGenerator = new Random();


public List<Question> getGeneratedRandomQuestions() {
    List<Question> randomQuestions = new ArrayList<>(NUMBER_OF_QUESTIONS);
    int randomQuestionElementsCapacity = getRandomQuestionElementsCapacity();
    Question question = new Question(randomQuestionElementsCapacity);
    for (int j = 0; j < randomQuestionElementsCapacity; j++) {
        boolean isLastIteration = j + 1 == randomQuestionElementsCapacity;
        QuestionElement questionElement = new QuestionElement();
        questionElement.setValue(getRandomQuestionElementValue());
        questionElement.setOperator(isLastIteration ? null
                : Operator.values()[randomGenerator.nextInt(Operator.values().length)]);
        question.addElement(questionElement);
    }
    randomQuestions.add(question);
    return randomQuestions;
}
private int getRandomQuestionElementsCapacity() {
    return getRandomIntegerFromRange(MIN_QUESTION_ELEMENTS, MAX_QUESTION_ELEMENTS);
}
private int getRandomQuestionElementValue() {
    return getRandomIntegerFromRange(MIN_QUESTION_ELEMENT_VALUE, MAX_QUESTION_ELEMENT_VALUE);
}
private int getRandomIntegerFromRange(int min, int max) {
    return randomGenerator.nextInt(max - min + 1) + min;
}


public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    RandomQuestions questionGenerator = new RandomQuestions();
    List<Question> randomQuestions = questionGenerator.getGeneratedRandomQuestions();
    for (Question question : randomQuestions) {
        System.out.println(""+ question+"=?");
        int answer = input.nextInt();
        if (answer == q.getValue()) {
            System.out.println("CORRECT");
        }else{
            System.err.println("STILL NOT WORKING");
        }
    }
}
}

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

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

如果我们坚持考虑操作员的优先级,计算正确的结果并不是很微不足道的。4 + 3 * 2应为10(不是14)。我相信,阅读有关分流码算法的信息应该为您带来一些帮助。这是解析数学表达式的算法,这只是计算其值的第一步,但仍然是第一步。

我建议以对象为导向的方法是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方法,但他们不再需要优先级。

最新更新