|
|
|
|
@ -0,0 +1,396 @@
|
|
|
|
|
import java.io.*;
|
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
|
|
// 用户类
|
|
|
|
|
class User {
|
|
|
|
|
private String username;
|
|
|
|
|
private String password;
|
|
|
|
|
private String type;
|
|
|
|
|
|
|
|
|
|
public User(String username, String password, String type) {
|
|
|
|
|
this.username = username;
|
|
|
|
|
this.password = password;
|
|
|
|
|
this.type = type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getUsername() { return username; }
|
|
|
|
|
public String getPassword() { return password; }
|
|
|
|
|
public String getType() { return type; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 抽象题目生成器
|
|
|
|
|
abstract class QuestionGenerator {
|
|
|
|
|
protected Random random = new Random();
|
|
|
|
|
|
|
|
|
|
public abstract String generateQuestion();
|
|
|
|
|
|
|
|
|
|
protected int generateNumber() {
|
|
|
|
|
return random.nextInt(100) + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected String generateOperator() {
|
|
|
|
|
String[] operators = {"+", "-", "*", "/"};
|
|
|
|
|
return operators[random.nextInt(operators.length)];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 小学题目生成器
|
|
|
|
|
class PrimaryQuestionGenerator extends QuestionGenerator {
|
|
|
|
|
@Override
|
|
|
|
|
public String generateQuestion() {
|
|
|
|
|
int operandCount = random.nextInt(3) + 2;
|
|
|
|
|
StringBuilder question = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
boolean hasParentheses = random.nextBoolean() && operandCount >= 3;
|
|
|
|
|
int parenthesesPosition = random.nextInt(operandCount - 1);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < operandCount; i++) {
|
|
|
|
|
if (hasParentheses && i == parenthesesPosition) {
|
|
|
|
|
question.append("(");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
question.append(generateNumber());
|
|
|
|
|
|
|
|
|
|
if (hasParentheses && i == parenthesesPosition + 1) {
|
|
|
|
|
question.append(")");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (i < operandCount - 1) {
|
|
|
|
|
question.append(" ").append(generateOperator()).append(" ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return question.toString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初中题目生成器
|
|
|
|
|
class JuniorQuestionGenerator extends QuestionGenerator {
|
|
|
|
|
@Override
|
|
|
|
|
public String generateQuestion() {
|
|
|
|
|
int operandCount = random.nextInt(3) + 2;
|
|
|
|
|
StringBuilder question = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
boolean hasSpecialOperator = false;
|
|
|
|
|
int specialOperatorPosition = random.nextInt(operandCount);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < operandCount; i++) {
|
|
|
|
|
if (i == specialOperatorPosition && !hasSpecialOperator) {
|
|
|
|
|
if (random.nextBoolean()) {
|
|
|
|
|
question.append(generateNumber()).append("^2"); // 改为^2表示平方
|
|
|
|
|
hasSpecialOperator = true;
|
|
|
|
|
} else {
|
|
|
|
|
question.append("√").append(generateNumber());
|
|
|
|
|
hasSpecialOperator = true;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
question.append(generateNumber());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (i < operandCount - 1) {
|
|
|
|
|
question.append(" ").append(generateOperator()).append(" ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!hasSpecialOperator) {
|
|
|
|
|
if (random.nextBoolean()) {
|
|
|
|
|
question.append(" ").append(generateOperator()).append(" ").append(generateNumber()).append("^2");
|
|
|
|
|
} else {
|
|
|
|
|
question.append(" ").append(generateOperator()).append(" ").append("√").append(generateNumber());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return question.toString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 高中题目生成器
|
|
|
|
|
class SeniorQuestionGenerator extends QuestionGenerator {
|
|
|
|
|
private final String[] trigFunctions = {"sin", "cos", "tan"};
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String generateQuestion() {
|
|
|
|
|
int operandCount = random.nextInt(3) + 2;
|
|
|
|
|
StringBuilder question = new StringBuilder();
|
|
|
|
|
|
|
|
|
|
boolean hasTrigFunction = false;
|
|
|
|
|
int trigPosition = random.nextInt(operandCount);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < operandCount; i++) {
|
|
|
|
|
if (i == trigPosition && !hasTrigFunction) {
|
|
|
|
|
String trigFunction = trigFunctions[random.nextInt(trigFunctions.length)];
|
|
|
|
|
question.append(trigFunction).append("(").append(generateNumber()).append(")");
|
|
|
|
|
hasTrigFunction = true;
|
|
|
|
|
} else {
|
|
|
|
|
question.append(generateNumber());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (i < operandCount - 1) {
|
|
|
|
|
question.append(" ").append(generateOperator()).append(" ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!hasTrigFunction) {
|
|
|
|
|
String trigFunction = trigFunctions[random.nextInt(trigFunctions.length)];
|
|
|
|
|
question.append(" ").append(generateOperator()).append(" ").append(trigFunction).append("(").append(generateNumber()).append(")");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return question.toString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 用户认证管理
|
|
|
|
|
class AuthenticationManager {
|
|
|
|
|
private Map<String, User> users;
|
|
|
|
|
|
|
|
|
|
public AuthenticationManager() {
|
|
|
|
|
users = new HashMap<String, User>();
|
|
|
|
|
initializeUsers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void initializeUsers() {
|
|
|
|
|
// 小学账户
|
|
|
|
|
users.put("张三1", new User("张三1", "123", "小学"));
|
|
|
|
|
users.put("张三2", new User("张三2", "123", "小学"));
|
|
|
|
|
users.put("张三3", new User("张三3", "123", "小学"));
|
|
|
|
|
|
|
|
|
|
// 初中账户
|
|
|
|
|
users.put("李四1", new User("李四1", "123", "初中"));
|
|
|
|
|
users.put("李四2", new User("李四2", "123", "初中"));
|
|
|
|
|
users.put("李四3", new User("李四3", "123", "初中"));
|
|
|
|
|
|
|
|
|
|
// 高中账户
|
|
|
|
|
users.put("王五1", new User("王五1", "123", "高中"));
|
|
|
|
|
users.put("王五2", new User("王五2", "123", "高中"));
|
|
|
|
|
users.put("王五3", new User("王五3", "123", "高中"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public User authenticate(String username, String password) {
|
|
|
|
|
User user = users.get(username);
|
|
|
|
|
if (user != null && user.getPassword().equals(password)) {
|
|
|
|
|
return user;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 文件管理类
|
|
|
|
|
class FileManager {
|
|
|
|
|
private static final String BASE_DIR = "exams";
|
|
|
|
|
|
|
|
|
|
public FileManager() {
|
|
|
|
|
File baseDir = new File(BASE_DIR);
|
|
|
|
|
if (!baseDir.exists()) {
|
|
|
|
|
baseDir.mkdir();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String generateFilename() {
|
|
|
|
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
|
|
|
|
|
return sdf.format(new Date()) + ".txt";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getUserDir(String username) {
|
|
|
|
|
return BASE_DIR + File.separator + username;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void saveQuestions(String username, List<String> questions) throws IOException {
|
|
|
|
|
String userDir = getUserDir(username);
|
|
|
|
|
File dir = new File(userDir);
|
|
|
|
|
if (!dir.exists()) {
|
|
|
|
|
dir.mkdir();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String filename = generateFilename();
|
|
|
|
|
String filepath = userDir + File.separator + filename;
|
|
|
|
|
|
|
|
|
|
// 使用GBK编码保存文件
|
|
|
|
|
try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(filepath), "GBK"))) {
|
|
|
|
|
for (int i = 0; i < questions.size(); i++) {
|
|
|
|
|
writer.println((i + 1) + ". " + questions.get(i));
|
|
|
|
|
if (i < questions.size() - 1) {
|
|
|
|
|
writer.println();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
System.out.println("题目已保存到: " + filepath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean checkDuplicate(String username, String question) {
|
|
|
|
|
String userDir = getUserDir(username);
|
|
|
|
|
File dir = new File(userDir);
|
|
|
|
|
|
|
|
|
|
if (!dir.exists()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
File[] files = dir.listFiles();
|
|
|
|
|
if (files == null) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (File file : files) {
|
|
|
|
|
try (Scanner scanner = new Scanner(file, "GBK")) {
|
|
|
|
|
while (scanner.hasNextLine()) {
|
|
|
|
|
String line = scanner.nextLine();
|
|
|
|
|
if (line.contains(question)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
// 忽略读取错误
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 主程序类
|
|
|
|
|
public class MathExamGenerator {
|
|
|
|
|
private AuthenticationManager authManager;
|
|
|
|
|
private FileManager fileManager;
|
|
|
|
|
private User currentUser;
|
|
|
|
|
private String currentType;
|
|
|
|
|
private Scanner scanner;
|
|
|
|
|
|
|
|
|
|
public MathExamGenerator() {
|
|
|
|
|
authManager = new AuthenticationManager();
|
|
|
|
|
fileManager = new FileManager();
|
|
|
|
|
scanner = new Scanner(System.in);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void start() {
|
|
|
|
|
System.out.println("===== 中小学数学卷子自动生成程序 =====");
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
if (currentUser == null) {
|
|
|
|
|
login();
|
|
|
|
|
} else {
|
|
|
|
|
generateExam();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void login() {
|
|
|
|
|
System.out.println("请输入用户名和密码(用空格隔开):");
|
|
|
|
|
String input = scanner.nextLine().trim();
|
|
|
|
|
|
|
|
|
|
if (input.equalsIgnoreCase("exit")) {
|
|
|
|
|
System.exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String[] parts = input.split(" ");
|
|
|
|
|
if (parts.length != 2) {
|
|
|
|
|
System.out.println("请输入正确的用户名、密码");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String username = parts[0];
|
|
|
|
|
String password = parts[1];
|
|
|
|
|
|
|
|
|
|
currentUser = authManager.authenticate(username, password);
|
|
|
|
|
if (currentUser != null) {
|
|
|
|
|
currentType = currentUser.getType();
|
|
|
|
|
System.out.println("当前选择为" + currentType + "出题");
|
|
|
|
|
} else {
|
|
|
|
|
System.out.println("请输入正确的用户名、密码");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void generateExam() {
|
|
|
|
|
System.out.println("准备生成" + currentType + "数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录):");
|
|
|
|
|
|
|
|
|
|
String input = scanner.nextLine().trim();
|
|
|
|
|
|
|
|
|
|
if (input.equals("-1")) {
|
|
|
|
|
currentUser = null;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (input.startsWith("切换为")) {
|
|
|
|
|
handleTypeSwitch(input);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int questionCount;
|
|
|
|
|
try {
|
|
|
|
|
questionCount = Integer.parseInt(input);
|
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
|
System.out.println("请输入有效的数字(10-30)或-1退出");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (questionCount != -1 && (questionCount < 10 || questionCount > 30)) {
|
|
|
|
|
System.out.println("题目数量应在10-30之间");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<String> questions = generateQuestions(questionCount);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
fileManager.saveQuestions(currentUser.getUsername(), questions);
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
System.out.println("保存文件时出错: " + e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void handleTypeSwitch(String input) {
|
|
|
|
|
Pattern pattern = Pattern.compile("切换为(小学|初中|高中)");
|
|
|
|
|
java.util.regex.Matcher matcher = pattern.matcher(input);
|
|
|
|
|
|
|
|
|
|
if (matcher.matches()) {
|
|
|
|
|
currentType = matcher.group(1);
|
|
|
|
|
System.out.println("准备生成" + currentType + "数学题目,请输入生成题目数量");
|
|
|
|
|
} else {
|
|
|
|
|
System.out.println("请输入小学、初中和高中三个选项中的一个");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<String> generateQuestions(int count) {
|
|
|
|
|
QuestionGenerator generator = getQuestionGenerator();
|
|
|
|
|
List<String> questions = new ArrayList<String>();
|
|
|
|
|
Set<String> generatedQuestions = new HashSet<String>();
|
|
|
|
|
|
|
|
|
|
int maxAttempts = count * 10;
|
|
|
|
|
int attempts = 0;
|
|
|
|
|
|
|
|
|
|
while (questions.size() < count && attempts < maxAttempts) {
|
|
|
|
|
String question = generator.generateQuestion();
|
|
|
|
|
|
|
|
|
|
if (!generatedQuestions.contains(question)) {
|
|
|
|
|
if (!fileManager.checkDuplicate(currentUser.getUsername(), question)) {
|
|
|
|
|
questions.add(question);
|
|
|
|
|
generatedQuestions.add(question);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
attempts++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (questions.size() < count) {
|
|
|
|
|
System.out.println("警告:由于题目重复,只生成了 " + questions.size() + " 道题目");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return questions;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private QuestionGenerator getQuestionGenerator() {
|
|
|
|
|
if ("小学".equals(currentType)) {
|
|
|
|
|
return new PrimaryQuestionGenerator();
|
|
|
|
|
} else if ("初中".equals(currentType)) {
|
|
|
|
|
return new JuniorQuestionGenerator();
|
|
|
|
|
} else if ("高中".equals(currentType)) {
|
|
|
|
|
return new SeniorQuestionGenerator();
|
|
|
|
|
} else {
|
|
|
|
|
return new PrimaryQuestionGenerator();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
MathExamGenerator generator = new MathExamGenerator();
|
|
|
|
|
generator.start();
|
|
|
|
|
}
|
|
|
|
|
}
|