You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
projectone/HighSchoolProblemGenerator....

85 lines
4.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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), "高中");
}
}