import java.text.DecimalFormat; import java.util.Random; public class HighSchoolProblemGenerator extends AbstractProblemGenerator { public HighSchoolProblemGenerator(Random random, DecimalFormat df) { super(random, df); } @Override public MathProblem generate() { int operandCount = random.nextInt(3) + 3; // 3-5 个操作数 double[] operandsVal = new double[operandCount]; String[] displayOperands = new String[operandCount]; String[] selectedOperators = new String[operandCount - 1]; // 生成基本操作数 for (int i = 0; i < operandCount; i++) { int v = random.nextInt(100) + 1; operandsVal[i] = v; displayOperands[i] = String.valueOf(v); } // 运算符选择(更均衡,避免连乘/连除) String previousOperator = null; double pPlus = 0.35, pMinus = 0.25, pTimes = 0.25, pDivide = 0.15; for (int i = 0; i < operandCount - 1; i++) { String operator; if ("*".equals(previousOperator) || "/".equals(previousOperator)) { double randValue = random.nextDouble(); double total = pPlus + pMinus; operator = randValue < (pPlus / total) ? "+" : "-"; } else { double randValue = random.nextDouble(); if (randValue < pPlus) operator = "+"; else if (randValue < pPlus + pMinus) operator = "-"; else if (randValue < pPlus + pMinus + pTimes) operator = "*"; else operator = "/"; } selectedOperators[i] = operator; previousOperator = operator; } // 三角函数 int trigIndex = random.nextInt(operandCount); String[] functions = {"sin", "cos", "tan"}; String function = functions[random.nextInt(functions.length)]; int[] angles = {0, 30, 45, 60, 90}; int angle = angles[random.nextInt(angles.length)]; if ("tan".equals(function) && angle == 90) angle = 60; // 避免 tan(90°) double trigVal = calculateTrigFunction(function, angle); operandsVal[trigIndex] = trigVal; displayOperands[trigIndex] = function + angle; // 括号选择(显示用 displayOperands,计算用 operandsVal) boolean addedBracket = false; int startPos = findBracketStart(operandsVal, selectedOperators, 0.3); StringBuilder expBuilder = new StringBuilder(); for (int i = 0; i < operandCount; i++) { if (startPos != -1 && i == startPos) expBuilder.append("("); expBuilder.append(displayOperands[i]); if (startPos != -1 && i == startPos + 1) expBuilder.append(")"); if (i < operandCount - 1) expBuilder.append(" ").append(selectedOperators[i]).append(" "); } String expression = expBuilder.toString(); // 计算结果(double) double result; if (startPos != -1) { double bracketResult = applyOperatorDouble(operandsVal[startPos], operandsVal[startPos + 1], selectedOperators[startPos]); int newCount = operandCount - 1; double[] newVals = new double[newCount]; String[] newOps = new String[newCount - 1]; for (int i = 0; i < startPos; i++) newVals[i] = operandsVal[i]; newVals[startPos] = bracketResult; for (int i = startPos + 1; i < newCount; i++) newVals[i] = operandsVal[i + 1]; for (int i = 0; i < newCount - 1; i++) newOps[i] = (i < startPos) ? selectedOperators[i] : selectedOperators[i + 1]; result = newVals[0]; for (int i = 0; i < newCount - 1; i++) result = applyOperatorDouble(result, newVals[i + 1], newOps[i]); } else { result = operandsVal[0]; for (int i = 0; i < operandCount - 1; i++) result = applyOperatorDouble(result, operandsVal[i + 1], selectedOperators[i]); } return new MathProblem(expression, df.format(result), "高中"); } }