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.
ERICPROJECT/src/PrimaryQuestionGenerator.java

95 lines
2.8 KiB

import java.util.ArrayList;
import java.util.List;
class PrimaryQuestionGenerator extends BaseQuestionGenerator {
@Override
protected String generateQuestion() {
List<String> numbers = generateNumbers();
List<String> operators = generateOperators(numbers);
List<String> tokens = combineTokens(numbers, operators);
addRandomBrackets(tokens);
return String.join(" ", tokens);
}
/**
* 生成操作数列表.
*/
private List<String> generateNumbers() {
int ops = randInt(2, Constants.MAX_OPERANDS);
List<String> numbers = new ArrayList<>();
for (int i = 0; i < ops; i++) {
numbers.add(String.valueOf(randInt(1, Constants.MAX_VALUE)));
}
return numbers;
}
/**
* 生成操作符列表,保证减法不产生负数.
*/
private List<String> generateOperators(List<String> numbers) {
List<String> operators = new ArrayList<>();
String current = numbers.getFirst();
for (int i = 1; i < numbers.size(); i++) {
String op = randomBasicOperator();
if ("-".equals(op)) {
int left = Integer.parseInt(current.replaceAll("[^0-9]", ""));
int right = Integer.parseInt(numbers.get(i));
if (left < right) {
op = random.nextBoolean() ? "+" : "*";
}
}
operators.add(op);
current = computeIntermediate(current, numbers.get(i), op);
}
return operators;
}
/**
* 合成数字和运算符为 tokens 列表.
*/
private List<String> combineTokens(List<String> numbers, List<String> operators) {
List<String> tokens = new ArrayList<>();
tokens.add(numbers.getFirst());
for (int i = 1; i < numbers.size(); i++) {
tokens.add(operators.get(i - 1));
tokens.add(numbers.get(i));
}
return tokens;
}
/**
* 随机为子表达式添加一对括号,不包裹整个表达式.
*/
private void addRandomBrackets(List<String> tokens) {
int ops = (tokens.size() + 1) / 2;
if (ops < 2 || !random.nextBoolean()) {
return;
}
int pairCount = ops - 1;
int chosenOpIndex = random.nextInt(pairCount);
int leftIndex = chosenOpIndex * 2;
int rightIndex = chosenOpIndex * 2 + 2;
if (!(leftIndex == 0 && rightIndex == tokens.size() - 1)) {
tokens.add(leftIndex, "(");
tokens.add(rightIndex + 2, ")");
}
}
/**
* 计算当前中间值,用于保证减法不产生负数.
*/
private String computeIntermediate(String current, String next, String op) {
int c = Integer.parseInt(current);
int n = Integer.parseInt(next);
return switch (op) {
case "*" -> String.valueOf(c * n);
case "+" -> String.valueOf(c + n);
case "/" -> n != 0 ? String.valueOf(c / n) : String.valueOf(c);
default -> String.valueOf(c); // 避免减法导致负数
};
}
}