You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MathLearningSoftware/src/com/mathlearning/model/PrimaryQuestionGenerator.java

143 lines
5.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.mathlearning.model;
import java.util.ArrayList;
import java.util.List;
public class PrimaryQuestionGenerator extends BaseQuestionGenerator {
@Override
public Question generateQuestion(int index) {
int operandCount = random.nextInt(4) + 2;
int[] operands = new int[operandCount];
int[] operations = new int[operandCount - 1];
String questionText;
double answer;
do {
generateOperands(operands, 1, 100);
generateOperations(operations, 4);
boolean useParentheses = random.nextDouble() < 0.3 && operandCount >= 3;
int[] parenthesesPositions = findParenthesesPositions(operations, useParentheses);
questionText = buildQuestionText(operands, operations,
parenthesesPositions[0], parenthesesPositions[1]);
answer = calculateAnswer(operands, operations,
parenthesesPositions[0], parenthesesPositions[1]);
} while (!isValidAnswer(answer));
return generateOptions(questionText, answer, "小学");
}
private int[] findParenthesesPositions(int[] operations, boolean useParentheses) {
int parenStart = -1;
int parenEnd = -1;
if (useParentheses) {
parenStart = findSuitableParenthesesPosition(operations);
if (parenStart != -1) {
parenEnd = parenStart + 1;
if (parenEnd < operations.length && random.nextBoolean()) {
parenEnd++;
}
}
}
return new int[]{parenStart, parenEnd};
}
private int findSuitableParenthesesPosition(int[] operations) {
List<Integer> suitablePositions = new ArrayList<>();
for (int i = 0; i < operations.length; i++) {
if ((operations[i] == 0 || operations[i] == 1) && i > 0) {
suitablePositions.add(i);
}
}
if (suitablePositions.isEmpty()) {
return operations.length > 1 ? random.nextInt(operations.length - 1) : -1;
}
return suitablePositions.get(random.nextInt(suitablePositions.size()));
}
private String buildQuestionText(int[] operands, int[] operations, int parenStart, int parenEnd) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < operands.length; i++) {
if (i == parenStart) sb.append("(");
sb.append(operands[i]);
if (i == parenEnd) sb.append(")");
if (i < operations.length) appendOperator(sb, operations[i]);
}
sb.append(" = ?");
return sb.toString();
}
private double calculateAnswer(int[] operands, int[] operations, int parenStart, int parenEnd) {
if (parenStart == -1 || parenEnd == -1) {
return calculateWithoutParentheses(operands, operations);
}
return calculateWithParentheses(operands, operations, parenStart, parenEnd);
}
private double calculateWithParentheses(int[] operands, int[] operations, int parenStart, int parenEnd) {
// 修改使用Double列表
List<Double> numbers = new ArrayList<>();
List<Integer> ops = new ArrayList<>();
for (int operand : operands) numbers.add((double) operand);
for (int operation : operations) ops.add(operation);
double parenthesesResult = calculateParenthesesContent(numbers, ops, parenStart, parenEnd);
if (!isValidAnswer(parenthesesResult)) return -1;
replaceWithParenthesesResult(numbers, ops, parenStart, parenEnd, parenthesesResult);
// 修改:调用新的方法名
return calculateDoubleList(numbers, ops);
}
private double calculateParenthesesContent(List<Double> numbers, List<Integer> ops, int start, int end) {
List<Double> parenNumbers = new ArrayList<>();
List<Integer> parenOps = new ArrayList<>();
for (int i = start; i <= end; i++) parenNumbers.add(numbers.get(i));
for (int i = start; i < end; i++) parenOps.add(ops.get(i));
// 修改:调用新的方法名
return calculateDoubleList(parenNumbers, parenOps);
}
private void replaceWithParenthesesResult(List<Double> numbers, List<Integer> ops,
int start, int end, double result) {
int numCountToRemove = end - start + 1;
int opCountToRemove = end - start;
for (int i = 0; i < numCountToRemove; i++) numbers.remove(start);
for (int i = 0; i < opCountToRemove; i++) ops.remove(start);
// 修改直接添加double结果不转换为int
numbers.add(start, result);
}
// 修改:重命名方法,避免与父类冲突
private double calculateDoubleList(List<Double> numbers, List<Integer> ops) {
double[] doubleNumbers = new double[numbers.size()];
for (int i = 0; i < numbers.size(); i++) {
doubleNumbers[i] = numbers.get(i);
}
int[] intOps = new int[ops.size()];
for (int i = 0; i < ops.size(); i++) {
intOps[i] = ops.get(i);
}
return calculateExpression(doubleNumbers, intOps);
}
}