|
|
|
|
@ -54,12 +54,13 @@ public class ChoiceQuestionGenerator {
|
|
|
|
|
* 生成小学题目
|
|
|
|
|
*/
|
|
|
|
|
private Question generatePrimaryQuestion(int questionNumber) {
|
|
|
|
|
int a = MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE);
|
|
|
|
|
int b = MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE);
|
|
|
|
|
// 随机选择运算符号数量(1-3个)
|
|
|
|
|
int operatorCount = 1 + random.nextInt(3);
|
|
|
|
|
|
|
|
|
|
String operation = getRandomOperation("+*-");
|
|
|
|
|
String questionText = String.format("%d %s %d = ?", a, operation, b);
|
|
|
|
|
int correctAnswer = calculate(a, b, operation);
|
|
|
|
|
// 生成复合运算表达式
|
|
|
|
|
String[] expression = generateCompoundExpression(operatorCount);
|
|
|
|
|
String questionText = expression[0];
|
|
|
|
|
int correctAnswer = Integer.parseInt(expression[1]);
|
|
|
|
|
|
|
|
|
|
// 生成错误选项
|
|
|
|
|
List<Integer> options = generateWrongOptions(correctAnswer);
|
|
|
|
|
@ -79,11 +80,15 @@ public class ChoiceQuestionGenerator {
|
|
|
|
|
* 生成初中题目
|
|
|
|
|
*/
|
|
|
|
|
private Question generateJuniorQuestion(int questionNumber) {
|
|
|
|
|
int a = MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE);
|
|
|
|
|
// 随机选择运算符号数量(1-3个)
|
|
|
|
|
int operatorCount = 1 + random.nextInt(3);
|
|
|
|
|
|
|
|
|
|
// 50%概率生成平方或开方题目
|
|
|
|
|
// 30%概率生成平方/开方题目,70%概率生成复合运算题目
|
|
|
|
|
if (random.nextDouble() < 0.3) {
|
|
|
|
|
// 生成平方或开方题目
|
|
|
|
|
if (random.nextBoolean()) {
|
|
|
|
|
// 平方题目
|
|
|
|
|
int a = MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE);
|
|
|
|
|
String questionText = String.format("%d² = ?", a);
|
|
|
|
|
int correctAnswer = a * a;
|
|
|
|
|
List<Integer> options = generateWrongOptions(correctAnswer);
|
|
|
|
|
@ -106,6 +111,25 @@ public class ChoiceQuestionGenerator {
|
|
|
|
|
options.add(correctAnswer);
|
|
|
|
|
Collections.shuffle(options);
|
|
|
|
|
|
|
|
|
|
return new Question(questionText,
|
|
|
|
|
String.valueOf(options.get(0)),
|
|
|
|
|
String.valueOf(options.get(1)),
|
|
|
|
|
String.valueOf(options.get(2)),
|
|
|
|
|
String.valueOf(options.get(3)),
|
|
|
|
|
String.valueOf(correctAnswer),
|
|
|
|
|
questionNumber);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 生成复合运算表达式(包含除法)
|
|
|
|
|
String[] expression = generateCompoundExpressionWithDivision(operatorCount);
|
|
|
|
|
String questionText = expression[0];
|
|
|
|
|
int correctAnswer = Integer.parseInt(expression[1]);
|
|
|
|
|
|
|
|
|
|
// 生成错误选项
|
|
|
|
|
List<Integer> options = generateWrongOptions(correctAnswer);
|
|
|
|
|
options.add(correctAnswer);
|
|
|
|
|
Collections.shuffle(options);
|
|
|
|
|
|
|
|
|
|
return new Question(questionText,
|
|
|
|
|
String.valueOf(options.get(0)),
|
|
|
|
|
String.valueOf(options.get(1)),
|
|
|
|
|
@ -120,7 +144,12 @@ public class ChoiceQuestionGenerator {
|
|
|
|
|
* 生成高中题目
|
|
|
|
|
*/
|
|
|
|
|
private Question generateSeniorQuestion(int questionNumber) {
|
|
|
|
|
// 使用常见角度: 0°, 30°, 45°, 60°, 90°, 120°, 135°, 150°, 180°, 210°, 225°, 270°, 300°, 315°, 330°
|
|
|
|
|
// 随机选择运算符号数量(1-3个)
|
|
|
|
|
int operatorCount = 1 + random.nextInt(3);
|
|
|
|
|
|
|
|
|
|
// 40%概率生成三角函数题目,60%概率生成复合运算题目
|
|
|
|
|
if (random.nextDouble() < 0.4) {
|
|
|
|
|
// 生成三角函数题目
|
|
|
|
|
int[] commonAngles = {0, 30, 45, 60, 90, 120, 135, 150, 180, 210, 225, 270, 300, 315, 330};
|
|
|
|
|
int angle = commonAngles[random.nextInt(commonAngles.length)];
|
|
|
|
|
String[] functions = {"sin", "cos", "tan"};
|
|
|
|
|
@ -144,6 +173,25 @@ public class ChoiceQuestionGenerator {
|
|
|
|
|
options.get(3),
|
|
|
|
|
correctAnswer,
|
|
|
|
|
questionNumber);
|
|
|
|
|
} else {
|
|
|
|
|
// 生成复合运算表达式(包含更复杂的运算)
|
|
|
|
|
String[] expression = generateAdvancedCompoundExpression(operatorCount);
|
|
|
|
|
String questionText = expression[0];
|
|
|
|
|
int correctAnswer = Integer.parseInt(expression[1]);
|
|
|
|
|
|
|
|
|
|
// 生成错误选项
|
|
|
|
|
List<Integer> options = generateWrongOptions(correctAnswer);
|
|
|
|
|
options.add(correctAnswer);
|
|
|
|
|
Collections.shuffle(options);
|
|
|
|
|
|
|
|
|
|
return new Question(questionText,
|
|
|
|
|
String.valueOf(options.get(0)),
|
|
|
|
|
String.valueOf(options.get(1)),
|
|
|
|
|
String.valueOf(options.get(2)),
|
|
|
|
|
String.valueOf(options.get(3)),
|
|
|
|
|
String.valueOf(correctAnswer),
|
|
|
|
|
questionNumber);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -356,6 +404,246 @@ private double calculateTrigFunction(String function, int angle) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成复合运算表达式
|
|
|
|
|
* @param operatorCount 运算符数量(1-3个)
|
|
|
|
|
* @return 返回[表达式字符串, 计算结果字符串]
|
|
|
|
|
*/
|
|
|
|
|
private String[] generateCompoundExpression(int operatorCount) {
|
|
|
|
|
StringBuilder expression = new StringBuilder();
|
|
|
|
|
List<Integer> operands = new ArrayList<>();
|
|
|
|
|
List<String> operators = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
// 生成操作数(运算符数量+1个操作数)
|
|
|
|
|
for (int i = 0; i <= operatorCount; i++) {
|
|
|
|
|
operands.add(MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成运算符
|
|
|
|
|
String[] availableOps = {"+", "-", "*"};
|
|
|
|
|
for (int i = 0; i < operatorCount; i++) {
|
|
|
|
|
operators.add(availableOps[random.nextInt(availableOps.length)]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建表达式字符串
|
|
|
|
|
expression.append(operands.get(0));
|
|
|
|
|
for (int i = 0; i < operatorCount; i++) {
|
|
|
|
|
expression.append(" ").append(operators.get(i)).append(" ").append(operands.get(i + 1));
|
|
|
|
|
}
|
|
|
|
|
expression.append(" = ?");
|
|
|
|
|
|
|
|
|
|
// 计算表达式结果
|
|
|
|
|
int result = calculateCompoundExpression(operands, operators);
|
|
|
|
|
|
|
|
|
|
return new String[]{expression.toString(), String.valueOf(result)};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成包含除法的复合运算表达式
|
|
|
|
|
*/
|
|
|
|
|
private String[] generateCompoundExpressionWithDivision(int operatorCount) {
|
|
|
|
|
StringBuilder expression = new StringBuilder();
|
|
|
|
|
List<Integer> operands = new ArrayList<>();
|
|
|
|
|
List<String> operators = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
// 生成操作数(运算符数量+1个操作数)
|
|
|
|
|
for (int i = 0; i <= operatorCount; i++) {
|
|
|
|
|
operands.add(MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成运算符(包含除法)
|
|
|
|
|
String[] availableOps = {"+", "-", "*", "/"};
|
|
|
|
|
for (int i = 0; i < operatorCount; i++) {
|
|
|
|
|
operators.add(availableOps[random.nextInt(availableOps.length)]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建表达式字符串
|
|
|
|
|
expression.append(operands.get(0));
|
|
|
|
|
for (int i = 0; i < operatorCount; i++) {
|
|
|
|
|
expression.append(" ").append(operators.get(i)).append(" ").append(operands.get(i + 1));
|
|
|
|
|
}
|
|
|
|
|
expression.append(" = ?");
|
|
|
|
|
|
|
|
|
|
// 计算表达式结果
|
|
|
|
|
int result = calculateCompoundExpressionWithDivision(operands, operators);
|
|
|
|
|
|
|
|
|
|
return new String[]{expression.toString(), String.valueOf(result)};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 计算复合表达式
|
|
|
|
|
*/
|
|
|
|
|
private int calculateCompoundExpression(List<Integer> operands, List<String> operators) {
|
|
|
|
|
// 先处理乘除法,再处理加减法
|
|
|
|
|
List<Integer> numbers = new ArrayList<>(operands);
|
|
|
|
|
List<String> ops = new ArrayList<>(operators);
|
|
|
|
|
|
|
|
|
|
// 第一轮:处理乘除法
|
|
|
|
|
for (int i = 0; i < ops.size(); i++) {
|
|
|
|
|
if (ops.get(i).equals("*")) {
|
|
|
|
|
int result = numbers.get(i) * numbers.get(i + 1);
|
|
|
|
|
numbers.set(i, result);
|
|
|
|
|
numbers.remove(i + 1);
|
|
|
|
|
ops.remove(i);
|
|
|
|
|
i--; // 调整索引
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 第二轮:处理加减法
|
|
|
|
|
int result = numbers.get(0);
|
|
|
|
|
for (int i = 0; i < ops.size(); i++) {
|
|
|
|
|
if (ops.get(i).equals("+")) {
|
|
|
|
|
result += numbers.get(i + 1);
|
|
|
|
|
} else if (ops.get(i).equals("-")) {
|
|
|
|
|
result -= numbers.get(i + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成高级复合运算表达式(包含平方运算)
|
|
|
|
|
*/
|
|
|
|
|
private String[] generateAdvancedCompoundExpression(int operatorCount) {
|
|
|
|
|
StringBuilder expression = new StringBuilder();
|
|
|
|
|
List<Integer> operands = new ArrayList<>();
|
|
|
|
|
List<String> operators = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
// 生成操作数(运算符数量+1个操作数)
|
|
|
|
|
for (int i = 0; i <= operatorCount; i++) {
|
|
|
|
|
operands.add(MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 生成运算符(包含平方运算)
|
|
|
|
|
String[] availableOps = {"+", "-", "*", "/", "²"};
|
|
|
|
|
for (int i = 0; i < operatorCount; i++) {
|
|
|
|
|
operators.add(availableOps[random.nextInt(availableOps.length)]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 构建表达式字符串
|
|
|
|
|
expression.append(operands.get(0));
|
|
|
|
|
for (int i = 0; i < operatorCount; i++) {
|
|
|
|
|
if (operators.get(i).equals("²")) {
|
|
|
|
|
expression.append("²");
|
|
|
|
|
} else {
|
|
|
|
|
expression.append(" ").append(operators.get(i)).append(" ").append(operands.get(i + 1));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
expression.append(" = ?");
|
|
|
|
|
|
|
|
|
|
// 计算表达式结果
|
|
|
|
|
int result = calculateAdvancedCompoundExpression(operands, operators);
|
|
|
|
|
|
|
|
|
|
return new String[]{expression.toString(), String.valueOf(result)};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 计算包含除法的复合表达式
|
|
|
|
|
*/
|
|
|
|
|
private int calculateCompoundExpressionWithDivision(List<Integer> operands, List<String> operators) {
|
|
|
|
|
// 先处理乘除法,再处理加减法
|
|
|
|
|
List<Integer> numbers = new ArrayList<>(operands);
|
|
|
|
|
List<String> ops = new ArrayList<>(operators);
|
|
|
|
|
|
|
|
|
|
// 第一轮:处理乘除法
|
|
|
|
|
for (int i = 0; i < ops.size(); i++) {
|
|
|
|
|
if (ops.get(i).equals("*")) {
|
|
|
|
|
int result = numbers.get(i) * numbers.get(i + 1);
|
|
|
|
|
numbers.set(i, result);
|
|
|
|
|
numbers.remove(i + 1);
|
|
|
|
|
ops.remove(i);
|
|
|
|
|
i--; // 调整索引
|
|
|
|
|
} else if (ops.get(i).equals("/")) {
|
|
|
|
|
if (numbers.get(i + 1) != 0) {
|
|
|
|
|
int result = numbers.get(i) / numbers.get(i + 1);
|
|
|
|
|
numbers.set(i, result);
|
|
|
|
|
numbers.remove(i + 1);
|
|
|
|
|
ops.remove(i);
|
|
|
|
|
i--; // 调整索引
|
|
|
|
|
} else {
|
|
|
|
|
// 避免除零错误,重新生成
|
|
|
|
|
numbers.set(i + 1, 1 + random.nextInt(MAX_OPERAND_VALUE));
|
|
|
|
|
int result = numbers.get(i) / numbers.get(i + 1);
|
|
|
|
|
numbers.set(i, result);
|
|
|
|
|
numbers.remove(i + 1);
|
|
|
|
|
ops.remove(i);
|
|
|
|
|
i--; // 调整索引
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 第二轮:处理加减法
|
|
|
|
|
int result = numbers.get(0);
|
|
|
|
|
for (int i = 0; i < ops.size(); i++) {
|
|
|
|
|
if (ops.get(i).equals("+")) {
|
|
|
|
|
result += numbers.get(i + 1);
|
|
|
|
|
} else if (ops.get(i).equals("-")) {
|
|
|
|
|
result -= numbers.get(i + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 计算高级复合表达式(包含平方运算)
|
|
|
|
|
*/
|
|
|
|
|
private int calculateAdvancedCompoundExpression(List<Integer> operands, List<String> operators) {
|
|
|
|
|
// 先处理平方运算
|
|
|
|
|
List<Integer> numbers = new ArrayList<>(operands);
|
|
|
|
|
List<String> ops = new ArrayList<>(operators);
|
|
|
|
|
|
|
|
|
|
// 第一轮:处理平方运算
|
|
|
|
|
for (int i = 0; i < ops.size(); i++) {
|
|
|
|
|
if (ops.get(i).equals("²")) {
|
|
|
|
|
int result = numbers.get(i) * numbers.get(i);
|
|
|
|
|
numbers.set(i, result);
|
|
|
|
|
ops.remove(i);
|
|
|
|
|
i--; // 调整索引
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 第二轮:处理乘除法
|
|
|
|
|
for (int i = 0; i < ops.size(); i++) {
|
|
|
|
|
if (ops.get(i).equals("*")) {
|
|
|
|
|
int result = numbers.get(i) * numbers.get(i + 1);
|
|
|
|
|
numbers.set(i, result);
|
|
|
|
|
numbers.remove(i + 1);
|
|
|
|
|
ops.remove(i);
|
|
|
|
|
i--; // 调整索引
|
|
|
|
|
} else if (ops.get(i).equals("/")) {
|
|
|
|
|
if (numbers.get(i + 1) != 0) {
|
|
|
|
|
int result = numbers.get(i) / numbers.get(i + 1);
|
|
|
|
|
numbers.set(i, result);
|
|
|
|
|
numbers.remove(i + 1);
|
|
|
|
|
ops.remove(i);
|
|
|
|
|
i--; // 调整索引
|
|
|
|
|
} else {
|
|
|
|
|
// 避免除零错误,重新生成
|
|
|
|
|
numbers.set(i + 1, 1 + random.nextInt(MAX_OPERAND_VALUE));
|
|
|
|
|
int result = numbers.get(i) / numbers.get(i + 1);
|
|
|
|
|
numbers.set(i, result);
|
|
|
|
|
numbers.remove(i + 1);
|
|
|
|
|
ops.remove(i);
|
|
|
|
|
i--; // 调整索引
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 第三轮:处理加减法
|
|
|
|
|
int result = numbers.get(0);
|
|
|
|
|
for (int i = 0; i < ops.size(); i++) {
|
|
|
|
|
if (ops.get(i).equals("+")) {
|
|
|
|
|
result += numbers.get(i + 1);
|
|
|
|
|
} else if (ops.get(i).equals("-")) {
|
|
|
|
|
result -= numbers.get(i + 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取随机运算符
|
|
|
|
|
*/
|
|
|
|
|
|