修复除法解析问题

develop
jiazhuo 6 months ago
parent 272f318108
commit 2096bc27cc

@ -16,8 +16,9 @@ public class JuniorHighGenerator implements QuestionGenerator {
switch (type) {
case 0: // 基本四则运算(考虑优先级)
questionText = generateArithmeticQuestion();
correctAnswerValue = evaluateExpression(questionText.replace(" = ?", ""));
ExpressionResult exprResult = generateArithmeticQuestion();
questionText = exprResult.expression;
correctAnswerValue = exprResult.value;
isIntegerAnswer = (correctAnswerValue == (int)correctAnswerValue);
break;
@ -61,48 +62,143 @@ public class JuniorHighGenerator implements QuestionGenerator {
return new Question(questionText, options, correctIndex);
}
// 生成考虑优先级的算术题目
private String generateArithmeticQuestion() {
int operandCount = random.nextInt(3) + 2; // 2-4个操作数
StringBuilder question = new StringBuilder();
List<String> tokens = new ArrayList<>();
// 生成操作数
for (int i = 0; i < operandCount; i++) {
if (i > 0) {
// 随机选择运算符,考虑优先级
String[] availableOps;
if (i == 1 && operandCount > 2) {
// 第一个运算符倾向于用乘除,确保优先级测试
availableOps = new String[]{"×", "÷", "+", "-"};
} else {
availableOps = new String[]{"+", "-", "×", "÷"};
}
String op = availableOps[random.nextInt(availableOps.length)];
tokens.add(op);
question.append(" ").append(op).append(" ");
}
// 表达式和结果封装类
private static class ExpressionResult {
String expression;
double value;
ExpressionResult(String expression, double value) {
this.expression = expression;
this.value = value;
}
}
// 生成合适的操作数
int num;
if (tokens.size() > 0 && (tokens.get(tokens.size()-1).equals("÷"))) {
// 除法:生成能整除的数
num = generateDivisibleNumber();
// 生成考虑优先级的算术题目并同时计算结果
private ExpressionResult generateArithmeticQuestion() {
// 使用预定义的简单表达式模板,确保可计算
String[][] templates = {
{"%d + %d × %d", "先乘后加"},
{"%d × %d + %d", "先乘后加"},
{"%d - %d × %d", "先乘后减"},
{"%d × %d - %d", "先乘后减"},
{"%d + %d ÷ %d", "先除后加"},
{"%d ÷ %d + %d", "先除后加"},
{"%d - %d ÷ %d", "先除后减"},
{"%d ÷ %d - %d", "先除后减"},
{"%d × (%d + %d)", "先加后乘"},
{"(%d + %d) × %d", "先加后乘"},
{"%d × (%d - %d)", "先减后乘"},
{"(%d - %d) × %d", "先减后乘"}
};
String[] template = templates[random.nextInt(templates.length)];
String pattern = template[0];
String description = template[1];
// 生成合适的数字,确保计算有效
int a, b, c = 1;
double result = 0;
// 根据模板类型生成合适的数字
if (pattern.contains("÷")) {
// 除法模板确保除数不为0且能整除
if (pattern.startsWith("%d ÷")) {
// 第一个操作数是除法确保b能整除a
b = random.nextInt(9) + 1; // 1-9
a = b * (random.nextInt(5) + 1); // a是b的倍数
c = random.nextInt(10) + 1;
result = (double)a / b + (pattern.contains("+") ? c : -c);
} else if (pattern.contains("÷ %d +") || pattern.contains("÷ %d -")) {
// 其他位置的除法确保除数不为0
a = random.nextInt(10) + 1;
b = random.nextInt(9) + 1; // 1-9
c = random.nextInt(10) + 1;
result = (double)a / b + (pattern.contains("+") ? c : -c);
} else {
num = random.nextInt(30) + 1; // 1-30
// 中间的除法
a = random.nextInt(10) + 1;
b = random.nextInt(9) + 1; // 1-9
c = random.nextInt(10) + 1;
if (pattern.contains("+ %d ÷")) {
result = a + (double)b / c;
} else if (pattern.contains("- %d ÷")) {
result = a - (double)b / c;
}
}
tokens.add(String.valueOf(num));
question.append(num);
} else if (pattern.contains("(")) {
// 括号模板
a = random.nextInt(10) + 1;
b = random.nextInt(10) + 1;
c = random.nextInt(10) + 1;
if (pattern.contains("× (") && pattern.contains(" + ")) {
result = a * (b + c);
} else if (pattern.contains("× (") && pattern.contains(" - ")) {
result = a * (b - c);
} else if (pattern.contains(" + ") && pattern.contains(") ×")) {
result = (a + b) * c;
} else if (pattern.contains(" - ") && pattern.contains(") ×")) {
result = (a - b) * c;
}
} else {
// 基本四则运算
a = random.nextInt(10) + 1;
b = random.nextInt(10) + 1;
c = random.nextInt(10) + 1;
// 根据运算符计算结果
if (pattern.equals("%d + %d × %d")) {
result = a + b * c;
} else if (pattern.equals("%d × %d + %d")) {
result = a * b + c;
} else if (pattern.equals("%d - %d × %d")) {
result = a - b * c;
} else if (pattern.equals("%d × %d - %d")) {
result = a * b - c;
}
}
// 如果还没有计算结果,使用安全的表达式计算
if (result == 0) {
result = safeEvaluateExpression(pattern, a, b, c);
}
question.append(" = ?");
return question.toString();
String expression = String.format(pattern, a, b, c) + " = ?";
return new ExpressionResult(expression, result);
}
// 生成能整除的数(用于除法运算)
private int generateDivisibleNumber() {
int[] smallNumbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
return smallNumbers[random.nextInt(smallNumbers.length)];
// 安全的表达式计算
private double safeEvaluateExpression(String pattern, int a, int b, int c) {
try {
if (pattern.equals("%d + %d × %d")) {
return a + b * c;
} else if (pattern.equals("%d × %d + %d")) {
return a * b + c;
} else if (pattern.equals("%d - %d × %d")) {
return a - b * c;
} else if (pattern.equals("%d × %d - %d")) {
return a * b - c;
} else if (pattern.equals("%d + %d ÷ %d")) {
return a + (double)b / c;
} else if (pattern.equals("%d ÷ %d + %d")) {
return (double)a / b + c;
} else if (pattern.equals("%d - %d ÷ %d")) {
return a - (double)b / c;
} else if (pattern.equals("%d ÷ %d - %d")) {
return (double)a / b - c;
} else if (pattern.equals("%d × (%d + %d)")) {
return a * (b + c);
} else if (pattern.equals("(%d + %d) × %d")) {
return (a + b) * c;
} else if (pattern.equals("%d × (%d - %d)")) {
return a * (b - c);
} else if (pattern.equals("(%d - %d) × %d")) {
return (a - b) * c;
}
} catch (Exception e) {
System.err.println("计算表达式失败: " + String.format(pattern, a, b, c) + ", 错误: " + e.getMessage());
}
return 0;
}
// 计算简单运算(支持负数)
@ -115,66 +211,8 @@ public class JuniorHighGenerator implements QuestionGenerator {
}
}
// 计算表达式(考虑运算优先级)- 使用自定义解析器避免ScriptEngine问题
private double evaluateExpression(String expression) {
try {
// 移除空格
expression = expression.replaceAll(" ", "");
// 使用递归下降解析器计算表达式
return evaluate(expression);
} catch (Exception e) {
System.err.println("计算表达式失败: " + expression + ", 错误: " + e.getMessage());
return 0;
}
}
// 递归计算表达式
private double evaluate(String expr) {
if (expr.isEmpty()) return 0;
// 处理加减法
String[] plusMinus = expr.split("(?=[+-])", 2);
if (plusMinus.length > 1) {
double left = evaluate(plusMinus[0]);
double right = evaluate(plusMinus[1].substring(1));
return plusMinus[1].charAt(0) == '+' ? left + right : left - right;
}
// 处理乘除法
String[] multDiv = expr.split("(?=[×÷])", 2);
if (multDiv.length > 1) {
double left = evaluateTerm(multDiv[0]);
double right = evaluateTerm(multDiv[1].substring(1));
return multDiv[1].charAt(0) == '×' ? left * right : left / right;
}
// 处理基本项(数字或括号表达式)
return evaluateTerm(expr);
}
// 计算基本项
private double evaluateTerm(String term) {
if (term.startsWith("(") && term.endsWith(")")) {
return evaluate(term.substring(1, term.length() - 1));
}
// 处理平方符号
if (term.endsWith("²")) {
double base = evaluateTerm(term.substring(0, term.length() - 1));
return base * base;
}
try {
return Double.parseDouble(term);
} catch (NumberFormatException e) {
System.err.println("解析数字失败: " + term);
return 0;
}
}
private int getPerfectSquare() {
int[] perfectSquares = {1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400};
int[] perfectSquares = {1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144};
return perfectSquares[random.nextInt(perfectSquares.length)];
}
@ -190,32 +228,51 @@ public class JuniorHighGenerator implements QuestionGenerator {
used.add(correctStr);
// 生成3个错误选项
while (options.size() < 4) {
int attempts = 0;
while (options.size() < 4 && attempts < 50) {
attempts++;
double wrongValue;
String wrongStr;
do {
// 根据正确答案的大小调整变化范围
double range = Math.max(5, Math.abs(correctAnswer) * 0.3);
double variation = (random.nextDouble() * range) + 1;
boolean positive = random.nextBoolean();
// 根据正确答案调整变化范围
double baseRange = Math.max(2, Math.abs(correctAnswer) * 0.3);
double variation = (random.nextDouble() * baseRange) + 1;
boolean positive = random.nextBoolean();
wrongValue = correctAnswer + (positive ? variation : -variation);
wrongValue = correctAnswer + (positive ? variation : -variation);
if (isInteger) {
wrongValue = Math.round(wrongValue);
wrongStr = String.valueOf((int)wrongValue);
} else {
wrongValue = Math.round(wrongValue * 100) / 100.0;
wrongStr = String.format("%.2f", wrongValue);
}
} while (used.contains(wrongStr) || Double.isNaN(wrongValue) || Double.isInfinite(wrongValue));
if (isInteger) {
wrongValue = Math.round(wrongValue);
wrongStr = String.valueOf((int)wrongValue);
} else {
wrongValue = Math.round(wrongValue * 100) / 100.0;
wrongStr = String.format("%.2f", wrongValue);
}
if (!used.contains(wrongStr)) {
options.add(wrongStr);
used.add(wrongStr);
}
}
// 如果选项不够,添加一些固定选项
while (options.size() < 4) {
String extraOption;
if (isInteger) {
int extraValue = (int)correctAnswer + options.size() * 2 + 1;
extraOption = String.valueOf(extraValue);
} else {
double extraValue = correctAnswer + options.size() * 0.5 + 0.1;
extraOption = String.format("%.2f", extraValue);
}
options.add(wrongStr);
used.add(wrongStr);
if (!used.contains(extraOption)) {
options.add(extraOption);
used.add(extraOption);
}
}
Collections.shuffle(options);
return options;
}
}
}
Loading…
Cancel
Save