import java.text.DecimalFormat; import java.util.Random; /** * 抽象题目生成器:封装公共工具方法与共享状态 */ public abstract class AbstractProblemGenerator { protected final Random random; protected final DecimalFormat df; protected AbstractProblemGenerator(Random random, DecimalFormat df) { this.random = random; this.df = df; } /** * 子类实现具体题目生成逻辑 */ public abstract MathProblem generate(); // 构建带括号的表达式(只包两个操作数) protected String buildExpressionWithBrackets(int[] operands, String[] operators, int startPos) { StringBuilder expression = new StringBuilder(); for (int i = 0; i < operands.length; i++) { if (i == startPos) { expression.append("("); } expression.append(operands[i]); if (i == startPos + 1) { expression.append(")"); } if (i < operands.length - 1) { expression.append(" ").append(operators[i]).append(" "); } } return expression.toString(); } // 计算带括号的表达式结果(只合并两个操作数) protected double evaluateExpressionWithBrackets(int[] operands, String[] operators, int startPos) { double bracketResult = applyOperator(operands[startPos], operands[startPos + 1], operators[startPos]); int newOperandCount = operands.length - 1; int[] newOperands = new int[newOperandCount]; String[] newOperators = new String[newOperandCount - 1]; for (int i = 0; i < startPos; i++) newOperands[i] = operands[i]; newOperands[startPos] = (int) bracketResult; for (int i = startPos + 1; i < newOperandCount; i++) newOperands[i] = operands[i + 1]; for (int i = 0; i < newOperandCount - 1; i++) { if (i < startPos) newOperators[i] = operators[i]; else newOperators[i] = operators[i + 1]; } double result = newOperands[0]; for (int i = 0; i < newOperandCount - 1; i++) { result = applyOperator(result, newOperands[i + 1], newOperators[i]); } return result; } /** 应用运算符(整数右操作数) */ protected double applyOperator(double left, int right, String operator) { switch (operator) { case "+": return left + right; case "-": return left - right; case "*": return left * right; case "/": return right != 0 ? left / right : left; // 避免除以零 default: return left; } } /** 计算三角函数值 */ protected double calculateTrigFunction(String function, int angle) { double radians = Math.toRadians(angle); switch (function) { case "sin": return Math.sin(radians); case "cos": return Math.cos(radians); case "tan": if (angle == 90) return Double.POSITIVE_INFINITY; // tan(90°)未定义 return Math.tan(radians); default: return 0; } } /** Double 版本的运算符应用(用于包含三角函数的计算) */ protected double applyOperatorDouble(double left, double right, String operator) { switch (operator) { case "+": return left + right; case "-": return left - right; case "*": return left * right; case "/": return right != 0.0 ? left / right : left; // 避免除以零 default: return left; } } /** 将 int 数组转 double 数组 */ protected double[] toDoubleArray(int[] arr) { double[] out = new double[arr.length]; for (int i = 0; i < arr.length; i++) out[i] = arr[i]; return out; } /** * 选择括号起始位置:仅当能改变优先级,并且括号内结果不为 0 时返回有效下标,否则返回 -1 */ protected int findBracketStart(double[] values, String[] operators, double probability) { if (values == null || operators == null) return -1; if (values.length <= 3) return -1; // 至少 4 个操作数才有加括号的意义 if (random.nextDouble() >= probability) return -1; int maxStart = values.length - 2; // 仅包两个操作数 int[] candidateStarts = new int[Math.max(0, maxStart + 1)]; int candidateCount = 0; for (int s = 0; s <= maxStart; s++) { boolean insideLow = "+".equals(operators[s]) || "-".equals(operators[s]); boolean leftHigh = (s - 1) >= 0 && ("*".equals(operators[s - 1]) || "/".equals(operators[s - 1])); boolean rightHigh = (s + 1) < operators.length && ("*".equals(operators[s + 1]) || "/".equals(operators[s + 1])); if (insideLow && (leftHigh || rightHigh)) { candidateStarts[candidateCount++] = s; } } if (candidateCount == 0) return -1; int candidate = candidateStarts[random.nextInt(candidateCount)]; double bracketResult = applyOperatorDouble(values[candidate], values[candidate + 1], operators[candidate]); return (bracketResult != 0.0) ? candidate : -1; } }