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/AbstractQuestionGenerator.java

135 lines
4.7 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.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;
}
}