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.
individual/src/SeniorQuestionGenerator.java

164 lines
6.5 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.

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;
}
}