|
|
|
|
@ -0,0 +1,134 @@
|
|
|
|
|
import java.io.*;
|
|
|
|
|
import java.util.HashSet;
|
|
|
|
|
import java.util.Random;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
import java.util.Stack;
|
|
|
|
|
|
|
|
|
|
public abstract class AbstractQuestionGenerator implements QuestionGenerator {
|
|
|
|
|
|
|
|
|
|
protected Random random = new Random();
|
|
|
|
|
protected Set<String> generatedQuestions = new HashSet<>();
|
|
|
|
|
protected String username;
|
|
|
|
|
|
|
|
|
|
// 设置用户名用于查重
|
|
|
|
|
public void setUsername(String username) {
|
|
|
|
|
this.username = username;
|
|
|
|
|
loadExistingQuestions();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从文件中加载已存在的题目
|
|
|
|
|
protected void loadExistingQuestions() {
|
|
|
|
|
if (username == null) return;
|
|
|
|
|
|
|
|
|
|
File[] userFiles = QuestionManager.getUserQuestionFiles(username);
|
|
|
|
|
for (File file : userFiles) {
|
|
|
|
|
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
|
|
|
|
String line;
|
|
|
|
|
while ((line = reader.readLine()) != null) {
|
|
|
|
|
line = line.trim();
|
|
|
|
|
if (!line.isEmpty() && line.matches("^\\d+\\. .+")) {
|
|
|
|
|
// 提取题目内容(去除题号)
|
|
|
|
|
String question = line.replaceFirst("^\\d+\\. ", "");
|
|
|
|
|
String normalized = normalizeQuestion(question);
|
|
|
|
|
generatedQuestions.add(normalized);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
System.out.println("读取题目文件出错: " + e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 标准化题目格式用于比较
|
|
|
|
|
public String normalizeQuestion(String question) {
|
|
|
|
|
return question.replaceAll("\\s+", "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected String generateNumber() {
|
|
|
|
|
return String.valueOf(random.nextInt(100) + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String generateOperator(String[] operators) {
|
|
|
|
|
return operators[random.nextInt(operators.length)];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected boolean isQuestionUnique(String question) {
|
|
|
|
|
String normalized = normalizeQuestion(question);
|
|
|
|
|
return !generatedQuestions.contains(normalized);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected void addToGeneratedQuestions(String question) {
|
|
|
|
|
String normalized = normalizeQuestion(question);
|
|
|
|
|
generatedQuestions.add(normalized);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected boolean hasBalancedParentheses(String expression) {
|
|
|
|
|
Stack<Character> stack = new Stack<>();
|
|
|
|
|
for (char c : expression.toCharArray()) {
|
|
|
|
|
if (c == '(') {
|
|
|
|
|
stack.push(c);
|
|
|
|
|
} else if (c == ')') {
|
|
|
|
|
if (stack.isEmpty()) return false;
|
|
|
|
|
stack.pop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return stack.isEmpty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean isValidParentheses(String expression) {
|
|
|
|
|
expression = expression.replaceAll("\\s+", "");
|
|
|
|
|
|
|
|
|
|
if (!hasBalancedParentheses(expression)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (expression.startsWith("(") && expression.endsWith(")") &&
|
|
|
|
|
hasBalancedParentheses(expression.substring(1, expression.length() - 1))) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String[] parts = expression.split("[+\\-×÷]");
|
|
|
|
|
for (String part : parts) {
|
|
|
|
|
part = part.trim();
|
|
|
|
|
if (part.startsWith("(") && part.endsWith(")")) {
|
|
|
|
|
String inside = part.substring(1, part.length() - 1);
|
|
|
|
|
if (isSimpleOperand(inside)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean isSimpleOperand(String str) {
|
|
|
|
|
return str.matches("\\d+") || str.matches("√\\d+") || str.matches("\\d²+") ||
|
|
|
|
|
str.matches("sin[\\d°]+") || str.matches("cos[\\d°]+") || str.matches("tan[\\d°]+") ||
|
|
|
|
|
str.matches("sincos[\\d°]+") || str.matches("sintan[\\d°]+") || str.matches("cossin[\\d°]+") ||
|
|
|
|
|
str.matches("costan[\\d°]+") || str.matches("tansin[\\d°]+") || str.matches("tancos[\\d°]+");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected boolean hasOperator(String expression) {
|
|
|
|
|
return expression.contains("+") || expression.contains("-") ||
|
|
|
|
|
expression.contains("×") || expression.contains("÷");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected String ensureBalancedParentheses(String expression) {
|
|
|
|
|
int openCount = 0;
|
|
|
|
|
int closeCount = 0;
|
|
|
|
|
|
|
|
|
|
for (char c : expression.toCharArray()) {
|
|
|
|
|
if (c == '(') openCount++;
|
|
|
|
|
if (c == ')') closeCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (openCount > closeCount) {
|
|
|
|
|
expression += ")";
|
|
|
|
|
closeCount++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return expression;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|