|
|
|
|
@ -0,0 +1,85 @@
|
|
|
|
|
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), "高中");
|
|
|
|
|
}
|
|
|
|
|
}
|