From 34c2af894e464df2a15f14ec65a871e60a90cac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=8D=9A=E6=96=87?= <15549487+FX_YBW@user.noreply.gitee.com> Date: Fri, 26 Sep 2025 08:53:22 +0800 Subject: [PATCH] =?UTF-8?q?final2=20=E5=8A=9F=E8=83=BD=E5=AE=8C=E5=85=A8?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=EF=BC=8C=E6=9C=AA=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mathpuzzle/Main.java | 10 +- .../controller/StartController.java | 191 +++++++++------- src/mathpuzzle/entity/User.java | 46 ++-- src/mathpuzzle/service/CaculatePrimary.java | 67 ++++++ src/mathpuzzle/service/FileHandler.java | 42 ++-- .../service/JuniorHighGenerator.java | 207 +++++++++--------- .../service/PrimarySchoolGenerator.java | 128 ++++++----- .../service/QuestionDeduplicator.java | 74 ++++--- src/mathpuzzle/service/QuestionGenerator.java | 4 +- .../service/SeniorHighGenerator.java | 138 ++++++------ src/mathpuzzle/system/LogSystem.java | 11 +- 11 files changed, 528 insertions(+), 390 deletions(-) create mode 100644 src/mathpuzzle/service/CaculatePrimary.java diff --git a/src/mathpuzzle/Main.java b/src/mathpuzzle/Main.java index d08a083..27ea92f 100644 --- a/src/mathpuzzle/Main.java +++ b/src/mathpuzzle/Main.java @@ -1,9 +1,11 @@ package mathpuzzle; + import mathpuzzle.controller.StartController; public class Main { - public static void main(String[] args) { - StartController startController = new StartController(); - startController.start(); - } + + public static void main(String[] args) { + StartController startController = new StartController(); + startController.start(); + } } diff --git a/src/mathpuzzle/controller/StartController.java b/src/mathpuzzle/controller/StartController.java index e915f7e..9f8c2f3 100644 --- a/src/mathpuzzle/controller/StartController.java +++ b/src/mathpuzzle/controller/StartController.java @@ -1,96 +1,133 @@ package mathpuzzle.controller; -import java.io.BufferedReader; + import java.io.IOException; -import java.io.InputStreamReader; +import java.util.ArrayList; import java.util.List; import java.util.Scanner; import mathpuzzle.entity.User; -import mathpuzzle.service.*; +import mathpuzzle.service.FileHandler; +import mathpuzzle.service.JuniorHighGenerator; +import mathpuzzle.service.PrimarySchoolGenerator; +import mathpuzzle.service.QuestionDeduplicator; +import mathpuzzle.service.QuestionGenerator; +import mathpuzzle.service.SeniorHighGenerator; import mathpuzzle.system.LogSystem; - public class StartController { - private LogSystem logSystem = new LogSystem(); - private QuestionDeduplicator deduplicator = new QuestionDeduplicator(); - private FileHandler fileHandler = new FileHandler(); - //private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); - public void start() { - - logSystem.userHashMapInit(); - Scanner scanner = new Scanner(System.in); - while (true) { - User user = logSystem.login(); - if (user == null) { - continue; - } - while (true) { - System.out.println("准备生成 " + user.getLevel() + "数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录):"); - String input = scanner.nextLine(); - try { - if ("-1".equals(input)) { - System.out.println("退出当前用户"); - break; - } - int count = Integer.parseInt(input); - if (count < 10 || count > 30) { - System.out.println("题目数量必须在10-30之间!"); - continue; - } - handleQuestionGeneration(user, count); - } catch (NumberFormatException e) { - handleLevelSwitch(user, input); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + + private LogSystem logSystem = new LogSystem(); + private QuestionDeduplicator deduplicator = new QuestionDeduplicator(); + private FileHandler fileHandler = new FileHandler(); + + public void start() { + + logSystem.userHashMapInit(); + Scanner scanner = new Scanner(System.in); + while (true) { + User user = logSystem.login(); + if (user == null) { + continue; + } + while (true) { + System.out.println("准备生成" + user.getLevel() + + "数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录):"); + String input = scanner.nextLine(); + try { + if ("-1".equals(input)) { + System.out.println("退出当前用户"); + break; + } + int count = Integer.parseInt(input); + if (count < 10 || count > 30) { + System.out.println("题目数量必须在10-30之间!"); + continue; + } + handleQuestionGeneration(user, count); + } catch (NumberFormatException e) { + handleLevelSwitch(user, input); + } catch (IOException e) { + throw new RuntimeException(e); } + } } - private void handleLevelSwitch(User user, String input) { - if (input.startsWith("切换为")) { - String newLevel = input.substring(3); - if ("小学".equals(newLevel) || "初中".equals(newLevel) || "高中".equals(newLevel)) { - user.setLevel(newLevel); - } else { - System.out.println("请输入小学、初中和高中三个选项中的一个"); - } - } else { - System.out.println("无效输入。请输入题目数量或'切换为 XX'指令。"); - } + } + + private void handleLevelSwitch(User user, String input) { + if (input.startsWith("切换为")) { + String newLevel = input.substring(3); + if ("小学".equals(newLevel) || "初中".equals(newLevel) || "高中".equals(newLevel)) { + user.setLevel(newLevel); + } else { + System.out.println("请输入小学、初中和高中三个选项中的一个"); + } + } else { + System.out.println("无效输入。请输入题目数量或'切换为 XX'指令。"); } - private void handleQuestionGeneration(User user, int count) throws IOException { - // 根据用户级别创建生成器 - QuestionGenerator generator = createGenerator(user.getLevel()); - if (generator == null) { - System.out.println("不支持的题目类型: " + user.getLevel()); - return; - } + } + + private QuestionGenerator createGenerator(String level) { + switch (level) { + case "小学": + return new PrimarySchoolGenerator(); + case "初中": + return new JuniorHighGenerator(); + case "高中": + return new SeniorHighGenerator(); + default: + return null; + } + } - // 加载历史题目用于查重 - deduplicator.loadExistingQuestions(user); + // 处理题目生成,进行去重工作 + private void handleQuestionGeneration(User user, int count) throws IOException { + QuestionGenerator generator = createGenerator(user.getLevel()); + if (generator == null) { + System.out.println("不支持的题目类型: " + user.getLevel()); + return; + } - // 生成题目 - List questions = generator.generateQuestions(count); + // 加载该用户所有历史题目用于查重 + deduplicator.loadExistingQuestions(user); - // 显示题目 - for (int i = 0; i < questions.size(); i++) { - System.out.println((i + 1) + ". " + questions.get(i)); - } + List finalQuestions = new ArrayList<>(); + int generatedCount = 0; + int maxAttempts = 1000; // 防止因题目空间耗尽而无限循环 + int attempts = 0; + + while (generatedCount < count && attempts < maxAttempts) { + attempts++; + // 临时生成一个题目列表(这里可以优化为一次生成一个) + List tempQuestions = generator.generateQuestions(1); + if (tempQuestions.isEmpty()) { + continue; + } + + String newQuestion = tempQuestions.get(0); + // 移除末尾的 " =" 以便查重更准确(可选,取决于你如何存储历史题) + String questionForDedup = newQuestion.endsWith(" =") ? + newQuestion.substring(0, newQuestion.length() - 2) : newQuestion; - // 保存到文件 - fileHandler.savePaper(user, questions); - System.out.println("试卷已成功保存!"); + if (!deduplicator.isDuplicate(questionForDedup)) { + // 题目不重复,加入最终列表和查重集 + finalQuestions.add(newQuestion); + deduplicator.addQuestion(questionForDedup); // 加入本次会话的查重集,防止本次生成重复 + generatedCount++; + //System.out.println("生成一道题目"); + } + // 如果重复,则丢弃,循环继续 } - private QuestionGenerator createGenerator(String level) { - switch (level) { - case "小学": - return new PrimarySchoolGenerator(); - case "初中": - return new JuniorHighGenerator(); - case "高中": - return new SeniorHighGenerator(); - default: - return null; - } + if (generatedCount < count) { + System.out.println( + "警告:在尝试了 " + maxAttempts + " 次后,仅生成了 " + generatedCount + " 道不重复的题目。"); + } + + // 显示并保存题目 + for (int i = 0; i < finalQuestions.size(); i++) { + System.out.println((i + 1) + ". " + finalQuestions.get(i)); } + + fileHandler.savePaper(user, finalQuestions); + System.out.println("试卷已成功保存!"); + } } diff --git a/src/mathpuzzle/entity/User.java b/src/mathpuzzle/entity/User.java index 403fafd..e22935c 100644 --- a/src/mathpuzzle/entity/User.java +++ b/src/mathpuzzle/entity/User.java @@ -1,24 +1,30 @@ package mathpuzzle.entity; public class User { - private String name; - private String password; - private String level; - public User(String name, String password, String level) { - this.name = name; - this.password = password; - this.level = level; - } - public String getName() { - return name; - } - public String getPassword() { - return password; - } - public String getLevel() { - return level; - } - public void setLevel(String newLevel) { - level = newLevel; - } + + private final String name; + private final String password; + private String level; + + public User(String name, String password, String level) { + this.name = name; + this.password = password; + this.level = level; + } + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String getLevel() { + return level; + } + + public void setLevel(String newLevel) { + level = newLevel; + } } diff --git a/src/mathpuzzle/service/CaculatePrimary.java b/src/mathpuzzle/service/CaculatePrimary.java new file mode 100644 index 0000000..f21d83e --- /dev/null +++ b/src/mathpuzzle/service/CaculatePrimary.java @@ -0,0 +1,67 @@ +package mathpuzzle.service; + +import static mathpuzzle.service.PrimarySchoolGenerator.isNumeric; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +public class CaculatePrimary { + + private final Stack numStack = new Stack<>(); + private final Stack opStack = new Stack<>(); + private final Map precedence = new HashMap<>(); + + public double caculate(List expression) { + precedence.put("+", 1); + precedence.put("-", 1); + precedence.put("*", 2); + precedence.put("/", 2); + for (String opOrNum : expression) { + if (isNumeric(opOrNum)) { + numStack.push(Double.parseDouble(opOrNum)); + } else if (opOrNum.equals("(")) { + opStack.push(opOrNum); + } else if (opOrNum.equals(")")) { + while (!opStack.peek().equals("(") && !opStack.isEmpty()) { + doCaculte(); + } + opStack.pop(); + } else if (precedence.containsKey(opOrNum)) { + while (!opStack.isEmpty() && !opStack.peek().equals("(") + && precedence.get(opOrNum) <= precedence.get(opStack.peek())) { + doCaculte(); + } + opStack.push(opOrNum); + } + } + while (!opStack.isEmpty()) { + doCaculte(); + } + return numStack.pop(); + } + + public void doCaculte() { + String op = opStack.pop(); + double num2 = numStack.pop(); + double num1 = numStack.pop(); + switch (op) { + case "+": + numStack.push(num1 + num2); + break; + case "-": + numStack.push(num1 - num2); + break; + case "*": + numStack.push(num1 * num2); + break; + case "/": + numStack.push(num1 / num2); + break; + default: + break; + } + } +} + diff --git a/src/mathpuzzle/service/FileHandler.java b/src/mathpuzzle/service/FileHandler.java index c9f5fe2..a929365 100644 --- a/src/mathpuzzle/service/FileHandler.java +++ b/src/mathpuzzle/service/FileHandler.java @@ -1,4 +1,5 @@ package mathpuzzle.service; + import mathpuzzle.entity.User; import java.io.BufferedWriter; import java.io.FileWriter; @@ -11,32 +12,31 @@ import java.time.format.DateTimeFormatter; import java.util.List; /** - * 文件处理器 - * 负责创建用户目录和保存试卷文件 + * 文件处理器 负责创建用户目录和保存试卷文件 */ public class FileHandler { - public void ensureUserDirectory(User user) throws IOException { - String dirPath = "./" + user.getName(); - Path path = Paths.get(dirPath); - if (!Files.exists(path)) { - Files.createDirectories(path); - } + public void ensureUserDirectory(User user) throws IOException { + String dirPath = "./" + user.getName(); + Path path = Paths.get(dirPath); + if (!Files.exists(path)) { + Files.createDirectories(path); } + } - public void savePaper(User user, List questions) throws IOException { - ensureUserDirectory(user); - // 生成文件名:年-月-日-时-分-秒.txt - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss"); - String fileName = LocalDateTime.now().format(formatter) + ".txt"; - String filePath = "./" + user.getName() + "/" + fileName; + public void savePaper(User user, List questions) throws IOException { + ensureUserDirectory(user); + // 生成文件名:年-月-日-时-分-秒.txt + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss"); + String fileName = LocalDateTime.now().format(formatter) + ".txt"; + String filePath = "./" + user.getName() + "/" + fileName; - try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) { - for (int i = 0; i < questions.size(); i++) { - writer.write((i + 1) + ". " + questions.get(i)); // 添加题号 - writer.newLine(); - writer.newLine(); // 每题之间空一行 - } - } + try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) { + for (int i = 0; i < questions.size(); i++) { + writer.write((i + 1) + ". " + questions.get(i)); // 添加题号 + writer.newLine(); + writer.newLine(); // 每题之间空一行 + } } + } } diff --git a/src/mathpuzzle/service/JuniorHighGenerator.java b/src/mathpuzzle/service/JuniorHighGenerator.java index d3decdc..80d95a0 100644 --- a/src/mathpuzzle/service/JuniorHighGenerator.java +++ b/src/mathpuzzle/service/JuniorHighGenerator.java @@ -1,122 +1,127 @@ package mathpuzzle.service; -import java.util.*; import static mathpuzzle.service.PrimarySchoolGenerator.isNumeric; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + /** - * 初中题目生成器 - * 题目必须包含至少一个平方或开根号运算符 + * 初中题目生成器 题目必须包含至少一个平方或开根号运算符 */ public class JuniorHighGenerator implements QuestionGenerator { - private static final String[] ADVANCED_OPS = {"平方", "开根号"}; - private static final String[] OPERATORS = {"+", "-", "*", "/"}; - private final Random random = new Random(); - @Override - public List generateQuestions(int count) { - List questions = new ArrayList<>(); - for (int i = 0; i < count; i++) { - String question = generateSingleQuestion(); - questions.add(question); - } - return questions; + private static final String[] ADVANCED_OPS = {"平方", "开根号"}; + private static final String[] OPERATORS = {"+", "-", "*", "/"}; + private final Random random = new Random(); + + @Override + public List generateQuestions(int count) { + List questions = new ArrayList<>(); + for (int i = 0; i < count; i++) { + String question = generateSingleQuestion(); + questions.add(question); } + return questions; + } - private String generateSingleQuestion() { - List parts = new ArrayList<>(); - int operandCount = random.nextInt(5) + 1; - parts = generateBase(operandCount, parts); - // hasAdvancedOp用以检测下面的循环是否加入了高级运算符,如果没有就启动保底 - boolean hasAdvancedOp = false; - if (operandCount == 1) { - if ("平方".equals(ADVANCED_OPS[random.nextInt(ADVANCED_OPS.length)])) { - parts.add("平方"); - } else { - parts.set(0, "开根号" + parts.get(0)); - } - hasAdvancedOp = true; - } else { - // 遍历查找左括号的合理位置 - for(int i = 0; i < parts.size() - 2; i++) { - // 该位置要为操作数且随机添加括号 - if (isNumeric(parts.get(i)) && random.nextBoolean()) { - // 随机数看取出来的是不是开根号运算符 - if("开根号".equals(ADVANCED_OPS[random.nextInt(ADVANCED_OPS.length)])) { - parts = generateRoot(parts, i); - } - // 如果不是开根号就是平方运算 - else { - parts = generateSquare(parts, i); - } - hasAdvancedOp = true; - break; - } - } + private String generateSingleQuestion() { + List parts = new ArrayList<>(); + int operandCount = random.nextInt(5) + 1; + parts = generateBase(operandCount, parts); + // hasAdvancedOp用以检测下面的循环是否加入了高级运算符,如果没有就启动保底 + boolean hasAdvancedOp = false; + if (operandCount == 1) { + if ("平方".equals(ADVANCED_OPS[random.nextInt(ADVANCED_OPS.length)])) { + parts.add("平方"); + } else { + parts.set(0, "开根号" + parts.get(0)); + } + hasAdvancedOp = true; + } else { + // 遍历查找左括号的合理位置 + for (int i = 0; i < parts.size() - 2; i++) { + // 该位置要为操作数且随机添加括号 + if (isNumeric(parts.get(i)) && random.nextBoolean()) { + // 随机数看取出来的是不是开根号运算符 + if ("开根号".equals(ADVANCED_OPS[random.nextInt(ADVANCED_OPS.length)])) { + parts = generateRoot(parts, i); + } + // 如果不是开根号就是平方运算 + else { + parts = generateSquare(parts, i); + } + hasAdvancedOp = true; + break; } - // 启动保底强制加入一个高级运算符 - if(!hasAdvancedOp) { - parts = forceAddAdvancedOp(parts); - } - return String.join(" ", parts) + " ="; + } } - // 产生基本操作 - public List generateBase(int operandCount, List parts) { - for (int i = 0; i < operandCount; i++) { - int num = random.nextInt(100) + 1; - parts.add(String.valueOf(num)); - if (i < operandCount - 1) { - parts.add(OPERATORS[random.nextInt(OPERATORS.length)]); - } - } - return parts; + // 启动保底强制加入一个高级运算符 + if (!hasAdvancedOp) { + parts = forceAddAdvancedOp(parts); } - // 强制加入一个高级运算符 - public List forceAddAdvancedOp(List parts) { - String advancedOp = ADVANCED_OPS[random.nextInt(ADVANCED_OPS.length)]; - if ("平方".equals(advancedOp)) { - parts.add("平方"); - } else { // 开根号 - parts.set(0, "开根号(" + parts.get(0)); - parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")" ); - } - return parts; + return String.join(" ", parts) + " ="; + } + + // 产生基本操作 + public List generateBase(int operandCount, List parts) { + for (int i = 0; i < operandCount; i++) { + int num = random.nextInt(100) + 1; + parts.add(String.valueOf(num)); + if (i < operandCount - 1) { + parts.add(OPERATORS[random.nextInt(OPERATORS.length)]); + } + } + return parts; + } + + // 强制加入一个高级运算符 + public List forceAddAdvancedOp(List parts) { + String advancedOp = ADVANCED_OPS[random.nextInt(ADVANCED_OPS.length)]; + if ("平方".equals(advancedOp)) { + parts.add("平方"); + } else { // 开根号 + parts.set(0, "开根号(" + parts.get(0)); + parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")"); } + return parts; + } - public List generateRoot(List parts, int i) { - if(random.nextBoolean()) { - parts.set(i, "开根号(" + parts.get(i) + ")"); - } else { - parts.set(i, "开根号(" + parts.get(i)); - // 为避免随机数上限出现0,此处要单独判断一下左括号正好括住倒数第二个操作数的情况 - if (i == parts.size() - 3) { - parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")"); - } else { - while(true) { - int i2 = random.nextInt(parts.size() - 3 - i) + 2; - if(isNumeric(parts.get(i + i2))) { - parts.set(i + i2, parts.get(i + i2) + ")"); - break; - } - } - } + public List generateRoot(List parts, int i) { + if (random.nextBoolean()) { + parts.set(i, "开根号(" + parts.get(i) + ")"); + } else { + parts.set(i, "开根号(" + parts.get(i)); + // 为避免随机数上限出现0,此处要单独判断一下左括号正好括住倒数第二个操作数的情况 + if (i == parts.size() - 3) { + parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")"); + } else { + while (true) { + int i2 = random.nextInt(parts.size() - 3 - i) + 2; + if (isNumeric(parts.get(i + i2))) { + parts.set(i + i2, parts.get(i + i2) + ")"); + break; + } } - return parts; + } } + return parts; + } - public List generateSquare(List parts, int i) { - parts.set(i, "(" + parts.get(i)); - // 为避免随机数上限出现0,此处要单独判断一下左括号正好括住倒数第二个操作数的情况 - if (i == parts.size() - 3) { - parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")"); - } else { - while(true) { - int i2 = random.nextInt(parts.size() - 3 - i) + 2; - if(isNumeric(parts.get(i + i2))) { - parts.set(i + i2, parts.get(i + i2) + ")平方"); - break; - } - } + public List generateSquare(List parts, int i) { + parts.set(i, "(" + parts.get(i)); + // 为避免随机数上限出现0,此处要单独判断一下左括号正好括住倒数第二个操作数的情况 + if (i == parts.size() - 3) { + parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")"); + } else { + while (true) { + int i2 = random.nextInt(parts.size() - 3 - i) + 2; + if (isNumeric(parts.get(i + i2))) { + parts.set(i + i2, parts.get(i + i2) + ")平方"); + break; } - return parts; + } } + return parts; + } } diff --git a/src/mathpuzzle/service/PrimarySchoolGenerator.java b/src/mathpuzzle/service/PrimarySchoolGenerator.java index 21b311a..8e192bc 100644 --- a/src/mathpuzzle/service/PrimarySchoolGenerator.java +++ b/src/mathpuzzle/service/PrimarySchoolGenerator.java @@ -1,74 +1,88 @@ package mathpuzzle.service; -import java.util.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; /** - * 小学题目生成器 - * 题目仅包含 +, -, *, / 和 () + * 小学题目生成器 题目仅包含 +, -, *, / 和 () */ public class PrimarySchoolGenerator implements QuestionGenerator { - private static final String[] OPERATORS = {"+", "-", "*", "/"}; - private final Random random = new Random(); - @Override - public List generateQuestions(int count) { - List questions = new ArrayList<>(); - for (int i = 0; i < count; i++) { - String question = generateSingleQuestion(); - questions.add(question); - } - return questions; + private static final String[] OPERATORS = {"+", "-", "*", "/"}; + private final Random random = new Random(); + + @Override + public List generateQuestions(int count) { + List questions = new ArrayList<>(); + for (int i = 0; i < count; i++) { + String question = generateSingleQuestion(); + questions.add(question); } - private String generateSingleQuestion() { - int operandCount = random.nextInt(4) + 2; // 2-5个操作数 - List parts = new ArrayList<>(); - // 生成基础操作 - parts = generateBase(operandCount, parts); - // 简单添加括号逻辑:随机加一个括号 - if (operandCount > 2 && random.nextBoolean()) { - // 遍历查找左括号的合理位置 - for(int i = 0; i < parts.size() - 2; i++) { - // 该位置要为操作数且随机添加括号 - if (isNumeric(parts.get(i)) && random.nextBoolean()) { - parts.set(i, "(" + parts.get(i)); - // 为避免随机数上限出现0,此处要单独判断一下左括号正好括住倒数第二个操作数的情况 - if (i == parts.size() - 3) { - parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")"); - } else { - while(true) { - int i2 = random.nextInt(parts.size() - 3 - i) + 2; - if(isNumeric(parts.get(i + i2))) { - parts.set(i + i2, parts.get(i + i2) + ")"); - break; - } - } - } - break; + return questions; + } + + private String generateSingleQuestion() { + CaculatePrimary caculatePrimary = new CaculatePrimary(); + int operandCount = random.nextInt(4) + 2; // 2-5个操作数 + List parts = new ArrayList<>(); + while (true) { + // 生成基础操作 + parts = generateBase(operandCount, parts); + // 简单添加括号逻辑:随机加一个括号 + if (operandCount > 2 && random.nextBoolean()) { + // 遍历查找左括号的合理位置 + for (int i = 0; i < parts.size() - 2; i++) { + // 该位置要为操作数且随机添加括号 + if (isNumeric(parts.get(i)) && random.nextBoolean()) { + parts.add(i, "("); + i++; + // 为避免随机数上限出现0,此处要单独判断一下左括号正好括住倒数第二个操作数的情况 + if (i == parts.size() - 3) { + parts.add(")"); + } else { + while (true) { + int i2 = random.nextInt(parts.size() - 3 - i) + 2; + if (isNumeric(parts.get(i + i2))) { + parts.add(i + i2 + 1, ")"); + break; } + } } + break; + } } + } + if (caculatePrimary.caculate(parts) >= 0) { return String.join(" ", parts) + " ="; + } else { + parts.clear(); + } } + } - public static boolean isNumeric(String str) { - if (str == null || str.isEmpty()) { - return false; - } - try { - Double.parseDouble(str); - return true; - } catch (NumberFormatException e) { - return false; - } + public static boolean isNumeric(String str) { + if (str == null || str.isEmpty()) { + return false; } + try { + Double.parseDouble(str); + return true; + } catch (NumberFormatException e) { + return false; + } + } - public List generateBase(int operandCount, List parts) { - for (int i = 0; i < operandCount; i++) { - int num = random.nextInt(100) + 1; - parts.add(String.valueOf(num)); - if (i < operandCount - 1) { - parts.add(OPERATORS[random.nextInt(OPERATORS.length)]); - } - } - return parts; + public List generateBase(int operandCount, List parts) { + for (int i = 0; i < operandCount; i++) { + int num = random.nextInt(100) + 1; + parts.add(String.valueOf(num)); + if (i < operandCount - 1) { + parts.add(OPERATORS[random.nextInt(OPERATORS.length)]); + } } + return parts; + } + + } \ No newline at end of file diff --git a/src/mathpuzzle/service/QuestionDeduplicator.java b/src/mathpuzzle/service/QuestionDeduplicator.java index c2e1fe1..f8cfc21 100644 --- a/src/mathpuzzle/service/QuestionDeduplicator.java +++ b/src/mathpuzzle/service/QuestionDeduplicator.java @@ -1,53 +1,57 @@ package mathpuzzle.service; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; import mathpuzzle.entity.User; - -import java.io.*; import java.util.HashSet; import java.util.Set; /** - * 题目查重器 - * 负责加载历史题目并检查新题目是否重复 + * 题目查重器 负责加载历史题目并检查新题目是否重复 */ public class QuestionDeduplicator { - private Set existingQuestions = new HashSet<>(); - public void loadExistingQuestions(User user) { - existingQuestions.clear(); - String userDir = "./" + user.getName(); - File dir = new File(userDir); + private final Set existingQuestions = new HashSet<>(); - if (!dir.exists()) { - return; // 目录不存在,无历史题目 - } + public void loadExistingQuestions(User user) { + existingQuestions.clear(); + String userDir = "./" + user.getName(); + File dir = new File(userDir); + + if (!dir.exists()) { + return; // 目录不存在,无历史题目 + } - File[] files = dir.listFiles((d, name) -> name.endsWith(".txt")); - if (files == null) return; - - for (File file : files) { - try (BufferedReader br = new BufferedReader(new FileReader(file))) { - String line; - while ((line = br.readLine()) != null) { - // 只加载题目行,忽略题号和空行 - if (line.trim().isEmpty() || line.matches("\\d+\\. .*")) { - String questionContent = line.replaceFirst("\\d+\\. ", "").trim(); - if (!questionContent.isEmpty() && !questionContent.equals("=")) { - existingQuestions.add(questionContent); - } - } - } - } catch (IOException e) { - System.err.println("读取历史文件时出错: " + file.getName()); + File[] files = dir.listFiles((d, name) -> name.endsWith(".txt")); + if (files == null) { + return; + } + + for (File file : files) { + try (BufferedReader br = new BufferedReader(new FileReader(file))) { + String line; + while ((line = br.readLine()) != null) { + // 只加载题目行,忽略题号和空行 + if (line.trim().isEmpty() || line.matches("\\d+\\. .*")) { + String questionContent = line.replaceFirst("\\d+\\. ", "").trim(); + if (!questionContent.isEmpty() && !questionContent.equals("=")) { + existingQuestions.add(questionContent); } + } } + } catch (IOException e) { + System.err.println("读取历史文件时出错: " + file.getName()); + } } + } - public boolean isDuplicate(String question) { - return existingQuestions.contains(question); - } + public boolean isDuplicate(String question) { + return existingQuestions.contains(question); + } - public void addQuestion(String question) { - existingQuestions.add(question); - } + public void addQuestion(String question) { + existingQuestions.add(question); + } } diff --git a/src/mathpuzzle/service/QuestionGenerator.java b/src/mathpuzzle/service/QuestionGenerator.java index 8660559..87a575a 100644 --- a/src/mathpuzzle/service/QuestionGenerator.java +++ b/src/mathpuzzle/service/QuestionGenerator.java @@ -1,6 +1,8 @@ package mathpuzzle.service; + import java.util.List; public interface QuestionGenerator { - List generateQuestions(int count); + + List generateQuestions(int count); } diff --git a/src/mathpuzzle/service/SeniorHighGenerator.java b/src/mathpuzzle/service/SeniorHighGenerator.java index 76a3bda..b23ace3 100644 --- a/src/mathpuzzle/service/SeniorHighGenerator.java +++ b/src/mathpuzzle/service/SeniorHighGenerator.java @@ -1,84 +1,88 @@ package mathpuzzle.service; -import java.util.*; import static mathpuzzle.service.PrimarySchoolGenerator.isNumeric; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + /** - * 高中题目生成器 - * 题目必须包含至少一个 sin, cos, tan 三角函数运算符 + * 高中题目生成器 题目必须包含至少一个 sin, cos, tan 三角函数运算符 */ public class SeniorHighGenerator implements QuestionGenerator { - private static final String[] TRIG_FUNCS = {"sin", "cos", "tan"}; - private static final String[] OPERATORS = {"+", "-", "*", "/"}; - private final Random random = new Random(); - @Override - public List generateQuestions(int count) { - List questions = new ArrayList<>(); - for (int i = 0; i < count; i++) { - String question = generateSingleQuestion(); - questions.add(question); - } - return questions; + private static final String[] TRIG_FUNCS = {"sin", "cos", "tan"}; + private static final String[] OPERATORS = {"+", "-", "*", "/"}; + private final Random random = new Random(); + + @Override + public List generateQuestions(int count) { + List questions = new ArrayList<>(); + for (int i = 0; i < count; i++) { + String question = generateSingleQuestion(); + questions.add(question); } + return questions; + } - private String generateSingleQuestion() { - List parts = new ArrayList<>(); - int operandCount = random.nextInt(5) + 1; - parts = generateBase(operandCount, parts); - String advancedOp; - // hasAdvancedOp用以检测下面的循环是否加入了高级运算符,如果没有就启动保底 - if(operandCount == 1) { - advancedOp = TRIG_FUNCS[random.nextInt(TRIG_FUNCS.length)]; - parts.set(0, advancedOp + parts.get(0)); - } else { - // 遍历查找左括号的合理位置 - for(int i = 0; i < parts.size(); i++) { - // 最后一次循环保底生成高中三角函数 - if (i == parts.size()-1) { - advancedOp = TRIG_FUNCS[random.nextInt(TRIG_FUNCS.length)]; - parts.set(i, advancedOp + parts.get(i)); - } else if (isNumeric(parts.get(i)) && random.nextBoolean()) { // 随机数看是否为操作数且随即进入生成程序 - // 进入随机生成tan\sin\cos的程序 - parts = generateTrig(parts, i); - break; - } - } + private String generateSingleQuestion() { + List parts = new ArrayList<>(); + int operandCount = random.nextInt(5) + 1; + parts = generateBase(operandCount, parts); + String advancedOp; + // hasAdvancedOp用以检测下面的循环是否加入了高级运算符,如果没有就启动保底 + if (operandCount == 1) { + advancedOp = TRIG_FUNCS[random.nextInt(TRIG_FUNCS.length)]; + parts.set(0, advancedOp + parts.get(0)); + } else { + // 遍历查找左括号的合理位置 + for (int i = 0; i < parts.size(); i++) { + // 最后一次循环保底生成高中三角函数 + if (i == parts.size() - 1) { + advancedOp = TRIG_FUNCS[random.nextInt(TRIG_FUNCS.length)]; + parts.set(i, advancedOp + parts.get(i)); + } else if (isNumeric(parts.get(i)) && random.nextBoolean()) {// 随机数看是否为操作数且随即进入生成程序 + // 进入随机生成tan\sin\cos的程序 + parts = generateTrig(parts, i); + break; } - return String.join(" ", parts) + " ="; + } } - // 产生基本操作 - public List generateBase(int operandCount, List parts) { - for (int i = 0; i < operandCount; i++) { - int num = random.nextInt(100) + 1; - parts.add(String.valueOf(num)); - if (i < operandCount - 1) { - parts.add(OPERATORS[random.nextInt(OPERATORS.length)]); - } - } - return parts; + return String.join(" ", parts) + " ="; + } + + // 产生基本操作 + public List generateBase(int operandCount, List parts) { + for (int i = 0; i < operandCount; i++) { + int num = random.nextInt(100) + 1; + parts.add(String.valueOf(num)); + if (i < operandCount - 1) { + parts.add(OPERATORS[random.nextInt(OPERATORS.length)]); + } } + return parts; + } - // 产生三角函数运算符 - public List generateTrig(List parts, int i) { - String trigOp = TRIG_FUNCS[random.nextInt(TRIG_FUNCS.length)]; - if(random.nextBoolean()) { - parts.set(i, trigOp + parts.get(i)); - } else { - parts.set(i, trigOp + "(" + parts.get(i)); - // 为避免随机数上限出现0,此处要单独判断一下左括号正好括住倒数第二个操作数的情况 - if (i == parts.size() - 3) { - parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")"); - } else { - while(true) { - int i2 = random.nextInt(parts.size() - 3 - i) + 2; - if(isNumeric(parts.get(i + i2))) { - parts.set(i + i2, parts.get(i + i2) + ")"); - break; - } - } - } + // 产生三角函数运算符 + public List generateTrig(List parts, int i) { + String trigOp = TRIG_FUNCS[random.nextInt(TRIG_FUNCS.length)]; + if (random.nextBoolean()) { + parts.set(i, trigOp + parts.get(i)); + } else { + parts.set(i, trigOp + "(" + parts.get(i)); + // 为避免随机数上限出现0,此处要单独判断一下左括号正好括住倒数第二个操作数的情况 + if (i == parts.size() - 3) { + parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")"); + } else { + while (true) { + int i2 = random.nextInt(parts.size() - 3 - i) + 2; + if (isNumeric(parts.get(i + i2))) { + parts.set(i + i2, parts.get(i + i2) + ")"); + break; + } } - return parts; + } } + return parts; + } } diff --git a/src/mathpuzzle/system/LogSystem.java b/src/mathpuzzle/system/LogSystem.java index 86f2a83..6918d23 100644 --- a/src/mathpuzzle/system/LogSystem.java +++ b/src/mathpuzzle/system/LogSystem.java @@ -4,7 +4,7 @@ import java.util.HashMap; import java.util.Scanner; public class LogSystem { - private HashMap userHashMap = new HashMap(); + private final HashMap userHashMap = new HashMap<>(); public void userHashMapInit() { // 小学 userHashMap.put("张三1", new User("张三 1", "123", "小学")); @@ -27,21 +27,18 @@ public class LogSystem { String[] info = scanner.nextLine().split(" "); if(info.length != 2) { System.out.println("请输入正确格式"); - continue; } else { String name = info[0]; String password = info[1]; User user = userHashMap.get(name); if (user == null) { - System.out.println("输入正确的用户名、密码"); - continue; + System.out.println("请输入正确的用户名、密码"); } else if (!user.getPassword().equals(password)) { - System.out.println("输入正确的用户名、密码"); - continue; + System.out.println("请输入正确的用户名、密码"); } else { - System.out.println("登录成功"); + System.out.println("当前选择为" + user.getLevel() + "出题"); return user; } }