|
|
|
|
@ -0,0 +1,163 @@
|
|
|
|
|
public class SeniorQuestionGenerator extends AbstractQuestionGenerator{
|
|
|
|
|
private static final String[] OPERATORS = {"+", "-", "×", "÷"};
|
|
|
|
|
private static boolean h = false;
|
|
|
|
|
private static StringBuilder q;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String generateQuestion() {
|
|
|
|
|
int attempts = 0;
|
|
|
|
|
while (attempts < 100) {
|
|
|
|
|
attempts++;
|
|
|
|
|
|
|
|
|
|
int operandCount = random.nextInt(5) + 1; // 1~5个操作数
|
|
|
|
|
StringBuilder question = new StringBuilder();
|
|
|
|
|
boolean hasTrigOperator = false;
|
|
|
|
|
|
|
|
|
|
AddTrigOperator(operandCount, hasTrigOperator, question);
|
|
|
|
|
hasTrigOperator = h;
|
|
|
|
|
question = q;
|
|
|
|
|
ForceAddTrigOperator(hasTrigOperator, question);
|
|
|
|
|
hasTrigOperator = h;
|
|
|
|
|
question = q;
|
|
|
|
|
|
|
|
|
|
String result = addReasonableParentheses(question.toString(), operandCount);
|
|
|
|
|
result = ensureBalancedParentheses(result);
|
|
|
|
|
result = Revise(result);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (isQuestionUnique(result) && isValidParentheses(result) &&
|
|
|
|
|
(hasOperator(result) || hasTrigOperator)) {
|
|
|
|
|
addToGeneratedQuestions(result);
|
|
|
|
|
String regex = "(?<!\\s)\\)(?=[^)]*$)";
|
|
|
|
|
result = result.replaceAll(regex, " )");
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return "sin 30° + cos 45°"; // 备用题目
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String addReasonableParentheses(String expression, int operandCount) {
|
|
|
|
|
if (operandCount <= 2 || random.nextDouble() < 0.4) {
|
|
|
|
|
return expression;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String[] parts = expression.split(" ");
|
|
|
|
|
if (parts.length < 5) return expression;
|
|
|
|
|
|
|
|
|
|
StringBuilder newExpr = new StringBuilder();
|
|
|
|
|
int start = random.nextInt(Math.max(1, parts.length / 2 - 1));
|
|
|
|
|
int end = start + 1 + random.nextInt(Math.max(1, parts.length / 2 - start - 1));
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < parts.length; i++) {
|
|
|
|
|
if (i == start * 2 && start * 2 < parts.length - 3) {
|
|
|
|
|
newExpr.append("( ");
|
|
|
|
|
}
|
|
|
|
|
newExpr.append(parts[i]);
|
|
|
|
|
if (i == end * 2 && i < parts.length - 2 && end * 2 > start * 2 + 2) {
|
|
|
|
|
newExpr.append(" )");
|
|
|
|
|
}
|
|
|
|
|
if (i < parts.length - 1) {
|
|
|
|
|
newExpr.append(" ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return newExpr.toString().trim();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String Revise(String expression) {
|
|
|
|
|
|
|
|
|
|
if(!expression.contains("(")) {
|
|
|
|
|
return expression;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String[] parts = expression.split(" ");
|
|
|
|
|
int count = 0;
|
|
|
|
|
while(count < 2) {
|
|
|
|
|
count++;
|
|
|
|
|
for (int i = 1; i < parts.length - 1; i++) {
|
|
|
|
|
if (parts[i].equals("(") && (parts[i+1].equals("+") || parts[i+1].equals("-") || parts[i+1].equals("×") || parts[i+1].equals("÷"))) {
|
|
|
|
|
String t = parts[i];
|
|
|
|
|
parts[i] = parts[i+1];
|
|
|
|
|
parts[i+1] = t;
|
|
|
|
|
}
|
|
|
|
|
if (parts[i].equals(")") && (parts[i-1].equals("+") || parts[i-1].equals("-") || parts[i-1].equals("×") || parts[i-1].equals("÷")
|
|
|
|
|
|| parts[i-1].equals("cos") || parts[i-1].equals("sin") || parts[i-1].equals("tan") || parts[i-1].equals("sincos") || parts[i-1].equals("sintan")
|
|
|
|
|
|| parts[i-1].equals("cossin") || parts[i-1].equals("costan") || parts[i-1].equals("tansin") || parts[i-1].equals("tancos"))) {
|
|
|
|
|
String t = parts[i];
|
|
|
|
|
parts[i] = parts[i-1];
|
|
|
|
|
parts[i-1] = t;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
StringBuilder result = new StringBuilder();
|
|
|
|
|
for (int i = 0; i < parts.length; i++) {
|
|
|
|
|
if (!parts[i].isEmpty()) {
|
|
|
|
|
result.append(parts[i]).append(" ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result.toString();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void AddTrigOperator(int operandCount, boolean hasTrigOperator, StringBuilder question) {
|
|
|
|
|
for (int i = 0; i < operandCount; i++) {
|
|
|
|
|
// 决定是否添加三角函数
|
|
|
|
|
if (!hasTrigOperator && random.nextDouble() < 0.4) {
|
|
|
|
|
String trigOp = generateOperator(new String[]{"sin", "cos", "tan"});
|
|
|
|
|
int angle = random.nextInt(101);
|
|
|
|
|
|
|
|
|
|
// 随机决定是否嵌套三角函数(30%概率)
|
|
|
|
|
if (random.nextDouble() < 0.3) {
|
|
|
|
|
String nestedTrig = generateOperator(new String[]{"sin", "cos", "tan"});
|
|
|
|
|
while (nestedTrig.equals(trigOp)) {
|
|
|
|
|
nestedTrig = generateOperator(new String[]{"sin", "cos", "tan"});
|
|
|
|
|
}
|
|
|
|
|
question.append(trigOp).append(nestedTrig).append(" ").append(angle).append("°");
|
|
|
|
|
} else {
|
|
|
|
|
question.append(trigOp).append(" ").append(angle).append("°");
|
|
|
|
|
}
|
|
|
|
|
hasTrigOperator = true;
|
|
|
|
|
} else {
|
|
|
|
|
question.append(generateNumber());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (i < operandCount - 1) {
|
|
|
|
|
String operator = generateOperator(OPERATORS);
|
|
|
|
|
question.append(" ").append(operator).append(" ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
h = hasTrigOperator;
|
|
|
|
|
q = question;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ForceAddTrigOperator(boolean hasTrigOperator, StringBuilder question) {
|
|
|
|
|
// 如果还没有三角函数,强制添加一个
|
|
|
|
|
if (!hasTrigOperator) {
|
|
|
|
|
String[] parts = question.toString().split(" ");
|
|
|
|
|
int pos = random.nextInt(parts.length / 2 + 1) * 2;
|
|
|
|
|
if (pos >= parts.length) pos = parts.length - 1;
|
|
|
|
|
|
|
|
|
|
String trigOp = generateOperator(new String[]{"sin", "cos", "tan"});
|
|
|
|
|
int angle = random.nextInt(101);
|
|
|
|
|
|
|
|
|
|
// 随机决定是否嵌套
|
|
|
|
|
if (random.nextDouble() < 0.3) {
|
|
|
|
|
String nestedTrig = generateOperator(new String[]{"sin", "cos", "tan"});
|
|
|
|
|
while (nestedTrig.equals(trigOp)) {
|
|
|
|
|
nestedTrig = generateOperator(new String[]{"sin", "cos", "tan"});
|
|
|
|
|
}
|
|
|
|
|
parts[pos] = trigOp + nestedTrig + " " + angle + "°";
|
|
|
|
|
} else {
|
|
|
|
|
parts[pos] = trigOp + " " + angle + "°";
|
|
|
|
|
}
|
|
|
|
|
question = new StringBuilder(String.join(" ", parts));
|
|
|
|
|
hasTrigOperator = true;
|
|
|
|
|
}
|
|
|
|
|
h = hasTrigOperator;
|
|
|
|
|
q = question;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|