diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/exams/张三1/2025-09-28-20-12-09.txt b/exams/张三1/2025-09-28-20-12-09.txt new file mode 100644 index 0000000..ec3ee1e --- /dev/null +++ b/exams/张三1/2025-09-28-20-12-09.txt @@ -0,0 +1,29 @@ +1. 58 = + +2. 19 / 81 = + +3. 77 - 20 = + +4. (66 + 65 + 35 / 57) = + +5. 29 / 37 = + +6. (64 / 31) - 27 * 64 - 69 = + +7. ((97) * 83 * 39 + 23) = + +8. 72 - 85 = + +9. 30 - 79 + 63 + 82 = + +10. 95 - 26 = + +11. 13 - 98 = + +12. 36 - 55 = + +13. (((94 + 72) * 1) * 13) / 90 = + +14. 36 * 69 = + +15. (68 + 60) * 65 / 33 = diff --git a/exams/张三1/2025-09-28-23-06-51.txt b/exams/张三1/2025-09-28-23-06-51.txt new file mode 100644 index 0000000..5d84912 --- /dev/null +++ b/exams/张三1/2025-09-28-23-06-51.txt @@ -0,0 +1,31 @@ +1. 69 = + +2. (4 + 49 - 36 + 79) = + +3. 17 = + +4. ((83 + 61 - 26) + 24 * 93) = + +5. 65 = + +6. 16 / 66 = + +7. 5 / 93 = + +8. 33 / 11 = + +9. 91 = + +10. (22 - 13) + 70 + 40 / 59 = + +11. 88 = + +12. ((87) + 89) - 55 * 76 = + +13. 63 + 18 + 6 - 25 = + +14. 44 / 37 - 45 - 87 = + +15. ((74) + 53) / 31 / 54 = + +16. 91 / 9 + 55 * 38 = diff --git a/src/Main.java b/src/Main.java index 9f9933b..d986921 100644 --- a/src/Main.java +++ b/src/Main.java @@ -1,31 +1,45 @@ +import interfaces.LoginSystemInterface; +import interfaces.FileManagerInterface; +import models.User; +import models.DifficultyLevel; +import factories.ServiceFactory; +import services.QuestionGenerator; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); - LoginSystem loginSystem = new LoginSystem(); + + LoginSystemInterface loginSystem = ServiceFactory.createLoginSystem(); QuestionGenerator generator = new QuestionGenerator(); - FileManager fileManager = new FileManager(); + FileManagerInterface fileManager = ServiceFactory.createFileManager(); while (true) { - // 登录阶段 - User currentUser = loginSystem.login(scanner); + System.out.print("请输入用户名和密码(用空格隔开):"); + String input = scanner.nextLine().trim(); + String[] parts = input.split("\\s+"); + + if (parts.length != 2) { + System.out.println("请输入正确的用户名、密码"); + continue; + } + + User currentUser = loginSystem.login(parts[0], parts[1]); if (currentUser == null) { + System.out.println("请输入正确的用户名、密码"); continue; } System.out.println("当前选择为" + currentUser.getLevel().getDisplayName() + "出题"); - // 主循环 while (true) { System.out.println("准备生成" + currentUser.getLevel().getDisplayName() + "数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)"); - String input = scanner.nextLine().trim(); + String command = scanner.nextLine().trim(); - // 检查切换命令 - if (input.startsWith("切换为")) { - String levelName = input.substring(3).trim(); + if (command.startsWith("切换为")) { + String levelName = command.substring(3).trim(); DifficultyLevel newLevel = loginSystem.switchLevel(levelName); if (newLevel != null) { currentUser.setLevel(newLevel); @@ -35,21 +49,18 @@ public class Main { } } - // 检查退出命令 - if (input.equals("-1")) { + if (command.equals("-1")) { System.out.println("退出当前用户,重新登录..."); break; } - // 生成题目 try { - int count = Integer.parseInt(input); + int count = Integer.parseInt(command); if (count < 10 || count > 30) { System.out.println("题目数量应在10-30之间"); continue; } - // 生成题目并检查重复 String[] questions = generator.generateQuestions(currentUser.getLevel(), count, currentUser.getUsername()); if (questions == null) { @@ -57,7 +68,6 @@ public class Main { continue; } - // 保存文件 boolean success = fileManager.saveQuestions(currentUser, questions); if (success) { System.out.println("题目生成成功!"); diff --git a/src/Question.java b/src/Question.java deleted file mode 100644 index ae414c9..0000000 --- a/src/Question.java +++ /dev/null @@ -1,4 +0,0 @@ -public interface Question { - String generateQuestion(); - boolean isValid(); -} \ No newline at end of file diff --git a/src/factories/ServiceFactory.java b/src/factories/ServiceFactory.java new file mode 100644 index 0000000..b1b5a6a --- /dev/null +++ b/src/factories/ServiceFactory.java @@ -0,0 +1,16 @@ +package factories; + +import interfaces.LoginSystemInterface; +import interfaces.FileManagerInterface; +import services.LoginSystem; +import services.FileManager; + +public class ServiceFactory { + public static LoginSystemInterface createLoginSystem() { + return new LoginSystem(); + } + + public static FileManagerInterface createFileManager() { + return new FileManager(); + } +} \ No newline at end of file diff --git a/src/interfaces/FileManagerInterface.java b/src/interfaces/FileManagerInterface.java new file mode 100644 index 0000000..1820ced --- /dev/null +++ b/src/interfaces/FileManagerInterface.java @@ -0,0 +1,9 @@ +package interfaces; + +import models.User; +import java.util.Set; + +public interface FileManagerInterface { + boolean saveQuestions(User user, String[] questions); + Set loadExistingQuestions(String username); +} \ No newline at end of file diff --git a/src/interfaces/LoginSystemInterface.java b/src/interfaces/LoginSystemInterface.java new file mode 100644 index 0000000..8c740f0 --- /dev/null +++ b/src/interfaces/LoginSystemInterface.java @@ -0,0 +1,9 @@ +package interfaces; + +import models.User; +import models.DifficultyLevel; + +public interface LoginSystemInterface { + User login(String username, String password); + DifficultyLevel switchLevel(String levelName); +} \ No newline at end of file diff --git a/src/interfaces/QuestionInterface.java b/src/interfaces/QuestionInterface.java new file mode 100644 index 0000000..a258625 --- /dev/null +++ b/src/interfaces/QuestionInterface.java @@ -0,0 +1,10 @@ +package interfaces; + +import models.DifficultyLevel; + +public interface QuestionInterface { + String generateQuestion(); + boolean isValid(); + String getQuestionText(); + DifficultyLevel getDifficulty(); +} \ No newline at end of file diff --git a/src/DifficultyLevel.java b/src/models/DifficultyLevel.java similarity index 95% rename from src/DifficultyLevel.java rename to src/models/DifficultyLevel.java index b549d7f..7fb255d 100644 --- a/src/DifficultyLevel.java +++ b/src/models/DifficultyLevel.java @@ -1,24 +1,26 @@ -public enum DifficultyLevel { - PRIMARY("小学"), - JUNIOR("初中"), - SENIOR("高中"); - - private final String displayName; - - DifficultyLevel(String displayName) { - this.displayName = displayName; - } - - public String getDisplayName() { - return displayName; - } - - public static DifficultyLevel fromString(String text) { - for (DifficultyLevel level : DifficultyLevel.values()) { - if (level.displayName.equals(text)) { - return level; - } - } - return null; - } +package models; + +public enum DifficultyLevel { + PRIMARY("小学"), + JUNIOR("初中"), + SENIOR("高中"); + + private final String displayName; + + DifficultyLevel(String displayName) { + this.displayName = displayName; + } + + public String getDisplayName() { + return displayName; + } + + public static DifficultyLevel fromString(String text) { + for (DifficultyLevel level : DifficultyLevel.values()) { + if (level.displayName.equals(text)) { + return level; + } + } + return null; + } } \ No newline at end of file diff --git a/src/User.java b/src/models/User.java similarity index 91% rename from src/User.java rename to src/models/User.java index fa199e4..de9eee8 100644 --- a/src/User.java +++ b/src/models/User.java @@ -1,17 +1,18 @@ -public class User { - private String username; - private String password; - private DifficultyLevel level; - - public User(String username, String password, DifficultyLevel level) { - this.username = username; - this.password = password; - this.level = level; - } - - // Getter 和 Setter 方法 - public String getUsername() { return username; } - public String getPassword() { return password; } - public DifficultyLevel getLevel() { return level; } - public void setLevel(DifficultyLevel level) { this.level = level; } +package models; + +public class User { + private String username; + private String password; + private DifficultyLevel level; + + public User(String username, String password, DifficultyLevel level) { + this.username = username; + this.password = password; + this.level = level; + } + + public String getUsername() { return username; } + public String getPassword() { return password; } + public DifficultyLevel getLevel() { return level; } + public void setLevel(DifficultyLevel level) { this.level = level; } } \ No newline at end of file diff --git a/src/FileManager.java b/src/services/FileManager.java similarity index 86% rename from src/FileManager.java rename to src/services/FileManager.java index 9900915..ca8cfba 100644 --- a/src/FileManager.java +++ b/src/services/FileManager.java @@ -1,66 +1,68 @@ -import java.io.*; -import java.nio.file.*; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashSet; -import java.util.Set; - -public class FileManager { - private static final String BASE_DIR = "exams"; - - public boolean saveQuestions(User user, String[] questions) { - try { - // 创建用户目录 - Path userDir = Paths.get(BASE_DIR, user.getUsername()); - Files.createDirectories(userDir); - - // 生成文件名 - String timestamp = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()); - Path filePath = userDir.resolve(timestamp + ".txt"); - - // 写入文件 - try (PrintWriter writer = new PrintWriter(Files.newBufferedWriter(filePath))) { - for (int i = 0; i < questions.length; i++) { - writer.println(questions[i]); - if (i < questions.length - 1) { - writer.println(); // 题目之间空一行 - } - } - } - - return true; - } catch (IOException e) { - e.printStackTrace(); - return false; - } - } - - public Set loadExistingQuestions(String username) { - Set questions = new HashSet<>(); - Path userDir = Paths.get(BASE_DIR, username); - - if (!Files.exists(userDir)) { - return questions; - } - - try (DirectoryStream stream = Files.newDirectoryStream(userDir, "*.txt")) { - for (Path filePath : stream) { - try (BufferedReader reader = Files.newBufferedReader(filePath)) { - String line; - while ((line = reader.readLine()) != null) { - if (line.trim().isEmpty() || !line.contains(".")) { - continue; - } - // 提取题目内容(去掉题号) - String question = line.substring(line.indexOf(".") + 1).trim(); - questions.add(question); - } - } - } - } catch (IOException e) { - e.printStackTrace(); - } - - return questions; - } +package services; + +import interfaces.FileManagerInterface; +import models.User; +import java.io.*; +import java.nio.file.*; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +public class FileManager implements FileManagerInterface { + private static final String BASE_DIR = "exams"; + + @Override + public boolean saveQuestions(User user, String[] questions) { + try { + Path userDir = Paths.get(BASE_DIR, user.getUsername()); + Files.createDirectories(userDir); + + String timestamp = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()); + Path filePath = userDir.resolve(timestamp + ".txt"); + + try (PrintWriter writer = new PrintWriter(Files.newBufferedWriter(filePath))) { + for (int i = 0; i < questions.length; i++) { + writer.println(questions[i]); + if (i < questions.length - 1) { + writer.println(); + } + } + } + + return true; + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + + @Override + public Set loadExistingQuestions(String username) { + Set questions = new HashSet<>(); + Path userDir = Paths.get(BASE_DIR, username); + + if (!Files.exists(userDir)) { + return questions; + } + + try (DirectoryStream stream = Files.newDirectoryStream(userDir, "*.txt")) { + for (Path filePath : stream) { + try (BufferedReader reader = Files.newBufferedReader(filePath)) { + String line; + while ((line = reader.readLine()) != null) { + if (line.trim().isEmpty() || !line.contains(".")) { + continue; + } + String question = line.substring(line.indexOf(".") + 1).trim(); + questions.add(question); + } + } + } + } catch (IOException e) { + e.printStackTrace(); + } + + return questions; + } } \ No newline at end of file diff --git a/src/LoginSystem.java b/src/services/LoginSystem.java similarity index 58% rename from src/LoginSystem.java rename to src/services/LoginSystem.java index ae93435..8084fa4 100644 --- a/src/LoginSystem.java +++ b/src/services/LoginSystem.java @@ -1,62 +1,48 @@ -import java.util.HashMap; -import java.util.Map; -import java.util.Scanner; - -public class LoginSystem { - private Map users; - - public LoginSystem() { - initializeUsers(); - } - - private void initializeUsers() { - users = new HashMap<>(); - - // 小学账户 - users.put("张三1", new User("张三1", "123", DifficultyLevel.PRIMARY)); - users.put("张三2", new User("张三2", "123", DifficultyLevel.PRIMARY)); - users.put("张三3", new User("张三3", "123", DifficultyLevel.PRIMARY)); - - // 初中账户 - users.put("李四1", new User("李四1", "123", DifficultyLevel.JUNIOR)); - users.put("李四2", new User("李四2", "123", DifficultyLevel.JUNIOR)); - users.put("李四3", new User("李四3", "123", DifficultyLevel.JUNIOR)); - - // 高中账户 - users.put("王五1", new User("王五1", "123", DifficultyLevel.SENIOR)); - users.put("王五2", new User("王五2", "123", DifficultyLevel.SENIOR)); - users.put("王五3", new User("王五3", "123", DifficultyLevel.SENIOR)); - } - - public User login(Scanner scanner) { - while (true) { - System.out.print("请输入用户名和密码(用空格隔开):"); - String input = scanner.nextLine().trim(); - String[] parts = input.split("\\s+"); - - if (parts.length != 2) { - System.out.println("请输入正确的用户名、密码"); - continue; - } - - String username = parts[0]; - String password = parts[1]; - - User user = users.get(username); - if (user != null && user.getPassword().equals(password)) { - return user; - } else { - System.out.println("请输入正确的用户名、密码"); - } - } - } - - public DifficultyLevel switchLevel(String levelName) { - DifficultyLevel newLevel = DifficultyLevel.fromString(levelName); - if (newLevel == null) { - System.out.println("请输入小学、初中和高中三个选项中的一个"); - return null; - } - return newLevel; - } +package services; + +import interfaces.LoginSystemInterface; +import models.User; +import models.DifficultyLevel; +import java.util.HashMap; +import java.util.Map; + +public class LoginSystem implements LoginSystemInterface { + private Map users; + + public LoginSystem() { + initializeUsers(); + } + + private void initializeUsers() { + users = new HashMap<>(); + + users.put("张三1", new User("张三1", "123", DifficultyLevel.PRIMARY)); + users.put("张三2", new User("张三2", "123", DifficultyLevel.PRIMARY)); + users.put("张三3", new User("张三3", "123", DifficultyLevel.PRIMARY)); + users.put("李四1", new User("李四1", "123", DifficultyLevel.JUNIOR)); + users.put("李四2", new User("李四2", "123", DifficultyLevel.JUNIOR)); + users.put("李四3", new User("李四3", "123", DifficultyLevel.JUNIOR)); + users.put("王五1", new User("王五1", "123", DifficultyLevel.SENIOR)); + users.put("王五2", new User("王五2", "123", DifficultyLevel.SENIOR)); + users.put("王五3", new User("王五3", "123", DifficultyLevel.SENIOR)); + } + + @Override + public User login(String username, String password) { + User user = users.get(username); + if (user != null && user.getPassword().equals(password)) { + return user; + } + return null; + } + + @Override + public DifficultyLevel switchLevel(String levelName) { + DifficultyLevel newLevel = DifficultyLevel.fromString(levelName); + if (newLevel == null) { + System.out.println("请输入小学、初中和高中三个选项中的一个"); + return null; + } + return newLevel; + } } \ No newline at end of file diff --git a/src/QuestionGenerator.java b/src/services/MathQuestion.java similarity index 53% rename from src/QuestionGenerator.java rename to src/services/MathQuestion.java index 46d690f..4324b32 100644 --- a/src/QuestionGenerator.java +++ b/src/services/MathQuestion.java @@ -1,96 +1,86 @@ -import java.util.HashSet; -import java.util.Random; -import java.util.Set; - -public class QuestionGenerator { - private Random random; - private FileManager fileManager; - - public QuestionGenerator() { - random = new Random(); - fileManager = new FileManager(); - } - - public String[] generateQuestions(DifficultyLevel level, int count, String username) { - Set existingQuestions = fileManager.loadExistingQuestions(username); - Set newQuestions = new HashSet<>(); - String[] questions = new String[count]; - - for (int i = 0; i < count; i++) { - String question; - int attempts = 0; - - do { - question = generateSingleQuestion(level, i + 1); - attempts++; - if (attempts > 100) { - return null; // 避免无限循环 - } - } while (existingQuestions.contains(question) || newQuestions.contains(question)); - - newQuestions.add(question); - questions[i] = question; - } - - return questions; - } - - private String generateSingleQuestion(DifficultyLevel level, int questionNumber) { - int operandCount = random.nextInt(5) + 1; // 1-5个操作数 - StringBuilder question = new StringBuilder(questionNumber + ". "); - - switch (level) { - case PRIMARY: - question.append(generatePrimaryQuestion(operandCount)); - break; - case JUNIOR: - question.append(generateJuniorQuestion(operandCount)); - break; - case SENIOR: - question.append(generateSeniorQuestion(operandCount)); - break; - } - - question.append(" = "); - return question.toString(); - } - - private String generatePrimaryQuestion(int operandCount) { - String[] operators = {"+", "-", "*", "/"}; - StringBuilder question = new StringBuilder(); - - for (int i = 0; i < operandCount; i++) { - if (i > 0) { - question.append(" ").append(operators[random.nextInt(operators.length)]).append(" "); - } - question.append(random.nextInt(100) + 1); - - // 随机添加括号(小学难度) - if (operandCount > 2 && random.nextDouble() < 0.3) { - question.insert(0, "(").append(")"); - } - } - - return question.toString(); - } - - private String generateJuniorQuestion(int operandCount) { - String question = generatePrimaryQuestion(operandCount); - - // 确保至少有一个平方或开根号 - if (random.nextBoolean()) { - return "√" + (random.nextInt(100) + 1) + " + " + question; - } else { - return "(" + (random.nextInt(10) + 1) + ")² + " + question; - } - } - - private String generateSeniorQuestion(int operandCount) { - String question = generatePrimaryQuestion(operandCount); - String[] trigFunctions = {"sin", "cos", "tan"}; - - // 确保至少有一个三角函数 - return trigFunctions[random.nextInt(trigFunctions.length)] + - "(" + (random.nextInt(90) + 1) + "°) + " + question; - } +package services; + +import interfaces.QuestionInterface; +import models.DifficultyLevel; +import java.util.Random; + +public class MathQuestion implements QuestionInterface { + private String questionText; + private DifficultyLevel difficulty; + private Random random; + + public MathQuestion(DifficultyLevel difficulty) { + this.difficulty = difficulty; + this.random = new Random(); + this.questionText = generateQuestion(); + } + + @Override + public String generateQuestion() { + int operandCount = random.nextInt(5) + 1; + StringBuilder question = new StringBuilder(); + + switch (difficulty) { + case PRIMARY: + question.append(generatePrimaryQuestion(operandCount)); + break; + case JUNIOR: + question.append(generateJuniorQuestion(operandCount)); + break; + case SENIOR: + question.append(generateSeniorQuestion(operandCount)); + break; + } + + question.append(" = "); + return question.toString(); + } + + @Override + public boolean isValid() { + return questionText != null && !questionText.trim().isEmpty(); + } + + @Override + public String getQuestionText() { + return questionText; + } + + @Override + public DifficultyLevel getDifficulty() { + return difficulty; + } + + private String generatePrimaryQuestion(int operandCount) { + String[] operators = {"+", "-", "*", "/"}; + StringBuilder question = new StringBuilder(); + + for (int i = 0; i < operandCount; i++) { + if (i > 0) { + question.append(" ").append(operators[random.nextInt(operators.length)]).append(" "); + } + question.append(random.nextInt(100) + 1); + + if (operandCount > 2 && random.nextDouble() < 0.3) { + question.insert(0, "(").append(")"); + } + } + return question.toString(); + } + + private String generateJuniorQuestion(int operandCount) { + String question = generatePrimaryQuestion(operandCount); + if (random.nextBoolean()) { + return "√" + (random.nextInt(100) + 1) + " + " + question; + } else { + return "(" + (random.nextInt(10) + 1) + ")² + " + question; + } + } + + private String generateSeniorQuestion(int operandCount) { + String question = generatePrimaryQuestion(operandCount); + String[] trigFunctions = {"sin", "cos", "tan"}; + return trigFunctions[random.nextInt(trigFunctions.length)] + + "(" + (random.nextInt(90) + 1) + "°) + " + question; + } } \ No newline at end of file diff --git a/src/services/QuestionGenerator.java b/src/services/QuestionGenerator.java new file mode 100644 index 0000000..08ebb15 --- /dev/null +++ b/src/services/QuestionGenerator.java @@ -0,0 +1,42 @@ +package services; + +import interfaces.QuestionInterface; +import models.DifficultyLevel; +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +public class QuestionGenerator { + private Random random; + private FileManager fileManager; + + public QuestionGenerator() { + random = new Random(); + fileManager = new FileManager(); + } + + public String[] generateQuestions(DifficultyLevel level, int count, String username) { + Set existingQuestions = fileManager.loadExistingQuestions(username); + Set newQuestions = new HashSet<>(); + String[] questions = new String[count]; + + for (int i = 0; i < count; i++) { + QuestionInterface question; + int attempts = 0; + + do { + question = new MathQuestion(level); + attempts++; + if (attempts > 100) { + return null; + } + } while (existingQuestions.contains(question.getQuestionText()) || + newQuestions.contains(question.getQuestionText())); + + newQuestions.add(question.getQuestionText()); + questions[i] = (i + 1) + ". " + question.getQuestionText(); + } + + return questions; + } +} \ No newline at end of file diff --git a/软件工程导论-个人项目需求-2025.pdf b/软件工程导论-个人项目需求-2025.pdf new file mode 100644 index 0000000..27e68f0 Binary files /dev/null and b/软件工程导论-个人项目需求-2025.pdf differ