commit 675c7906a43e0a7b856ecb793cf06d38fad11d5d Author: tianyuan <2861334240@qq.com> Date: Fri Sep 26 13:15:31 2025 +0800 初始化 diff --git a/src/MathTestGenerator.java b/src/MathTestGenerator.java new file mode 100644 index 0000000..d5d4832 --- /dev/null +++ b/src/MathTestGenerator.java @@ -0,0 +1,398 @@ +import java.io.*; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * 中小学数学卷子自动生成程序 + * 作者:张三 + * 班级:软1班 + */ +public class MathTestGenerator { + + private static final Map USERS = new HashMap<>(); + static { + // 小学账户 + USERS.put("张三1", new User("张三1", "123", UserType.PRIMARY)); + USERS.put("张三2", new User("张三2", "123", UserType.PRIMARY)); + USERS.put("张三3", new User("张三3", "123", UserType.PRIMARY)); + // 初中账户 + USERS.put("李四1", new User("李四1", "123", UserType.JUNIOR)); + USERS.put("李四2", new User("李四2", "123", UserType.JUNIOR)); + USERS.put("李四3", new User("李四3", "123", UserType.JUNIOR)); + // 高中账户 + USERS.put("王五1", new User("王五1", "123", UserType.SENIOR)); + USERS.put("王五2", new User("王五2", "123", UserType.SENIOR)); + USERS.put("王五3", new User("王五3", "123", UserType.SENIOR)); + } + + // 用户类型枚举 + private enum UserType { + PRIMARY("小学"), JUNIOR("初中"), SENIOR("高中"); + + private final String name; + UserType(String name) { this.name = name; } + public String getName() { return name; } + } + + // 用户类 + private static class User { + String username; + String password; + UserType type; + + User(String username, String password, UserType type) { + this.username = username; + this.password = password; + this.type = type; + } + } + + // 运算符枚举 + private enum Operator { + ADD("+", 1), SUBTRACT("-", 1), MULTIPLY("*", 2), DIVIDE("/", 2), + POWER("^", 3), SQRT("√", 3), SIN("sin", 4), COS("cos", 4), TAN("tan", 4); + + private final String symbol; + private final int priority; + Operator(String symbol, int priority) { + this.symbol = symbol; + this.priority = priority; + } + public String getSymbol() { return symbol; } + public int getPriority() { return priority; } + } + + private User currentUser; + private UserType currentType; + private Set generatedQuestions; + private Scanner scanner; + private String baseDir; + + public MathTestGenerator() { + this.scanner = new Scanner(System.in); + this.generatedQuestions = new HashSet<>(); + this.baseDir = System.getProperty("user.dir") + File.separator + "papers"; + initializeStorage(); + } + + /** + * 初始化存储目录 + */ + private void initializeStorage() { + File dir = new File(baseDir); + if (!dir.exists()) { + dir.mkdirs(); + } + } + + /** + * 主程序入口 + */ + public void start() { + System.out.println("=== 中小学数学卷子自动生成程序 ==="); + + while (true) { + if (login()) { + generatePapers(); + } + } + } + + /** + * 用户登录 + */ + private boolean login() { + while (true) { + System.out.print("请输入用户名和密码(用空格隔开,输入exit退出程序):"); + String input = scanner.nextLine().trim(); + + if (input.equalsIgnoreCase("exit")) { + System.exit(0); + } + + String[] credentials = input.split("\\s+"); + if (credentials.length != 2) { + System.out.println("请输入正确的用户名、密码"); + continue; + } + + String username = credentials[0]; + String password = credentials[1]; + + User user = USERS.get(username); + if (user != null && user.password.equals(password)) { + currentUser = user; + currentType = user.type; + System.out.println("当前选择为" + currentType.getName() + "出题"); + loadGeneratedQuestions(); + return true; + } else { + System.out.println("请输入正确的用户名、密码"); + } + } + } + + /** + * 加载已生成的题目用于查重 + */ + private void loadGeneratedQuestions() { + generatedQuestions.clear(); + File userDir = new File(baseDir + File.separator + currentUser.username); + if (userDir.exists() && userDir.isDirectory()) { + File[] files = userDir.listFiles((dir, name) -> name.endsWith(".txt")); + if (files != null) { + for (File file : files) { + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String line; + while ((line = reader.readLine()) != null) { + if (line.matches("^\\d+\\.\\s+.+")) { + String question = line.substring(line.indexOf(".") + 1).trim(); + generatedQuestions.add(normalizeQuestion(question)); + } + } + } catch (IOException e) { + System.out.println("读取历史题目失败: " + e.getMessage()); + } + } + } + } + } + + /** + * 生成试卷 + */ + private void generatePapers() { + while (true) { + System.out.print("准备生成" + currentType.getName() + + "数学题目,请输入生成题目数量(10-30,输入-1退出当前用户):"); + + String input = scanner.nextLine().trim(); + + if (input.equals("-1")) { + currentUser = null; + currentType = null; + System.out.println("已退出当前用户,请重新登录"); + return; + } + + if (isSwitchCommand(input)) { + handleSwitchCommand(input); + continue; + } + + try { + int count = Integer.parseInt(input); + if (count >= 10 && count <= 30) { + generateTestPaper(count); + } else { + System.out.println("题目数量应在10-30之间"); + } + } catch (NumberFormatException e) { + System.out.println("请输入有效的数字"); + } + } + } + + /** + * 检查是否为切换命令 + */ + private boolean isSwitchCommand(String input) { + return input.startsWith("切换为"); + } + + /** + * 处理切换命令 + */ + private void handleSwitchCommand(String input) { + String typeStr = input.substring(3).trim(); + try { + UserType newType = UserType.valueOf(typeStr.toUpperCase()); + currentType = newType; + System.out.println("准备生成" + currentType.getName() + "数学题目,请输入生成题目数量"); + } catch (IllegalArgumentException e) { + System.out.println("请输入小学、初中和高中三个选项中的一个"); + } + } + + /** + * 生成试卷文件 + */ + private void generateTestPaper(int questionCount) { + List questions = new ArrayList<>(); + int generated = 0; + int attempts = 0; + final int MAX_ATTEMPTS = 1000; + + while (generated < questionCount && attempts < MAX_ATTEMPTS) { + String question = generateQuestion(); + String normalized = normalizeQuestion(question); + + if (!generatedQuestions.contains(normalized)) { + questions.add(question); + generatedQuestions.add(normalized); + generated++; + } + attempts++; + } + + if (generated < questionCount) { + System.out.println("警告:无法生成足够的不重复题目,已生成 " + generated + " 道题"); + } + + saveToFile(questions); + System.out.println("试卷生成成功!"); + } + + /** + * 生成单个题目 + */ + private String generateQuestion() { + Random random = new Random(); + int operandCount = random.nextInt(5) + 1; // 1-5个操作数 + StringBuilder question = new StringBuilder(); + List operands = new ArrayList<>(); + List operators = new ArrayList<>(); + + // 生成操作数 + for (int i = 0; i < operandCount; i++) { + operands.add(random.nextInt(100) + 1); + } + + // 根据难度生成运算符 + switch (currentType) { + case PRIMARY: + generatePrimaryOperators(operators, operandCount - 1, random); + break; + case JUNIOR: + generateJuniorOperators(operators, operandCount - 1, random); + break; + case SENIOR: + generateSeniorOperators(operators, operandCount - 1, random); + break; + } + + // 构建题目表达式 + question.append(operands.get(0)); + for (int i = 0; i < operators.size(); i++) { + Operator op = operators.get(i); + if (op == Operator.SQRT) { + question.insert(0, "√(").append(")"); + question.append(op.getSymbol()).append(operands.get(i + 1)); + } else if (op == Operator.SIN || op == Operator.COS || op == Operator.TAN) { + question.append(op.getSymbol()).append("(").append(operands.get(i + 1)).append(")"); + } else { + question.append(" ").append(op.getSymbol()).append(" ").append(operands.get(i + 1)); + } + } + + // 随机添加括号 + if (operandCount > 2 && random.nextBoolean()) { + question.insert(0, "("); + int insertPos = question.indexOf(" ", question.indexOf(" ") + 1); + if (insertPos != -1) { + question.insert(insertPos + 1, ")"); + } + } + + return question.toString(); + } + + /** + * 生成小学运算符 + */ + private void generatePrimaryOperators(List operators, int count, Random random) { + Operator[] primaryOps = {Operator.ADD, Operator.SUBTRACT, Operator.MULTIPLY, Operator.DIVIDE}; + for (int i = 0; i < count; i++) { + operators.add(primaryOps[random.nextInt(primaryOps.length)]); + } + } + + /** + * 生成初中运算符(必须包含平方或开根号) + */ + private void generateJuniorOperators(List operators, int count, Random random) { + Operator[] juniorOps = {Operator.ADD, Operator.SUBTRACT, Operator.MULTIPLY, Operator.DIVIDE, + Operator.POWER, Operator.SQRT}; + + // 确保至少有一个平方或开根号 + boolean hasSpecialOp = false; + for (int i = 0; i < count; i++) { + Operator op = juniorOps[random.nextInt(juniorOps.length)]; + if (op == Operator.POWER || op == Operator.SQRT) { + hasSpecialOp = true; + } + operators.add(op); + } + + if (!hasSpecialOp && count > 0) { + operators.set(random.nextInt(count), + random.nextBoolean() ? Operator.POWER : Operator.SQRT); + } + } + + /** + * 生成高中运算符(必须包含三角函数) + */ + private void generateSeniorOperators(List operators, int count, Random random) { + Operator[] seniorOps = {Operator.ADD, Operator.SUBTRACT, Operator.MULTIPLY, Operator.DIVIDE, + Operator.POWER, Operator.SQRT, Operator.SIN, Operator.COS, Operator.TAN}; + + // 确保至少有一个三角函数 + boolean hasTrigOp = false; + for (int i = 0; i < count; i++) { + Operator op = seniorOps[random.nextInt(seniorOps.length)]; + if (op == Operator.SIN || op == Operator.COS || op == Operator.TAN) { + hasTrigOp = true; + } + operators.add(op); + } + + if (!hasTrigOp && count > 0) { + Operator[] trigOps = {Operator.SIN, Operator.COS, Operator.TAN}; + operators.set(random.nextInt(count), trigOps[random.nextInt(trigOps.length)]); + } + } + + /** + * 规范化题目用于查重 + */ + private String normalizeQuestion(String question) { + return question.replaceAll("\\s+", "").toLowerCase(); + } + + /** + * 保存题目到文件 + */ + private void saveToFile(List questions) { + String timestamp = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()); + String filename = timestamp + ".txt"; + String userDirPath = baseDir + File.separator + currentUser.username; + + File userDir = new File(userDirPath); + if (!userDir.exists()) { + userDir.mkdirs(); + } + + File file = new File(userDir, filename); + try (PrintWriter writer = new PrintWriter(new FileWriter(file))) { + for (int i = 0; i < questions.size(); i++) { + writer.println((i + 1) + ". " + questions.get(i)); + if (i < questions.size() - 1) { + writer.println(); + } + } + } catch (IOException e) { + System.out.println("保存文件失败: " + e.getMessage()); + } + } + + + + /** + * 主方法 + */ + public static void main(String[] args) { + MathTestGenerator generator = new MathTestGenerator(); + generator.start(); + } +} \ No newline at end of file