diff --git a/README.md b/doc/README.md similarity index 100% rename from README.md rename to doc/README.md diff --git a/papers/张三1/2025-9-26-14-4-59.txt b/papers/张三1/2025-9-26-14-4-59.txt new file mode 100644 index 0000000..4a065fa --- /dev/null +++ b/papers/张三1/2025-9-26-14-4-59.txt @@ -0,0 +1,20 @@ +1. (19( * 18 * 80)) / 1 + +2. 25 / 5 + +3. (58 / 29 / 1 + 98) + +4. 34 * (47 / 1 * 59) + +5. (48 + 5 + 57) / 3 / 1 + +6. (16( * 100 / 2)) + +7. 53 / 1 + +8. ((81 * 41 / 1)) + +9. 84 / 2 + +10. (65 * 11 + 75) + diff --git a/papers/张三1/2025-9-27-16-14-18.txt b/papers/张三1/2025-9-27-16-14-18.txt new file mode 100644 index 0000000..c61ad86 --- /dev/null +++ b/papers/张三1/2025-9-27-16-14-18.txt @@ -0,0 +1,20 @@ +1. 66 / 33 = + +2. 98 + 55 = + +3. 2 + 88 = + +4. ((56 * 80 + 77)) = + +5. (80 / 5 + 56) + 60 * 62 = + +6. 47 * 62 + 85 * 66 / 1 = + +7. 69 / (3 / 1 / 1 + 48) = + +8. ((42 + 51 / 51 * )27) = + +9. 20 / 1 + 21 / 21 + 27 = + +10. 33 * 75 / (1 + 64 + 95) = + diff --git a/src/Main.java b/src/Main.java index 213a119..b742752 100644 --- a/src/Main.java +++ b/src/Main.java @@ -32,6 +32,13 @@ public class Main { private static final Map USER_MAP = new HashMap<>(); private static final String OUTPUT_ROOT = "papers"; // 每个账号一个子文件夹 private static final Random RANDOM = new Random(); + + // 常量定义 + private static final int MIN_QUESTIONS = 10; + private static final int MAX_QUESTIONS = 30; + private static final int MAX_ATTEMPTS_MULTIPLIER = 200; + private static final int MAX_OPERAND_VALUE = 100; + private static final int MIN_OPERAND_VALUE = 1; public static void main(String[] args) { initAccounts(); @@ -44,8 +51,8 @@ public class Main { Level currentLevel = login.level; System.out.println("当前选择为" + currentLevel + "出题"); // 登录后的工作循环 + System.out.println("准备生成" + currentLevel + "数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)"); while (true) { - System.out.println("准备生成" + currentLevel + "数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)"); String line = readLineTrim(scanner); if (line == null) return; // EOF // 支持命令:切换为XX @@ -57,6 +64,7 @@ public class Main { continue; } currentLevel = targetLevel; + System.out.println("准备生成" + currentLevel + "数学题目,请输入生成题目数量(输入-1将退出当前用户,重新登录)"); continue; } int count; @@ -137,11 +145,16 @@ public class Main { } return null; } + + // 通用的输入验证方法 + private static boolean isValidQuestionCount(int count) { + return count >= MIN_QUESTIONS && count <= MAX_QUESTIONS; + } private static List generateUniquePaper(Level level, int count, Set history) { Set set = new LinkedHashSet<>(); int attempts = 0; - int maxAttempts = count * 200; // 足够多的尝试次数以避免死循环 + int maxAttempts = count * MAX_ATTEMPTS_MULTIPLIER; // 足够多的尝试次数以避免死循环 while (set.size() < count && attempts < maxAttempts) { String q = generateQuestion(level); attempts++; @@ -155,27 +168,29 @@ public class Main { return new ArrayList<>(set); } - private static String generateQuestion(Level level) { - // 统一表达式末尾不加等号,以字符串完全相等进行去重 - return switch (level) { - case 小学 -> generatePrimary(); - case 初中 -> generateJunior(); - case 高中 -> generateSenior(); - default -> generatePrimary(); - }; + //==================== 面向接口的题目生成器 ==================== + interface QuestionGenerator { + String generate(); } - - private static String generatePrimary() { - // 仅使用 +, *, / 和括号,运算数 1-5 个,范围 1-100 - int operands = 2 + RANDOM.nextInt(4); // 2-5 + + // 通用字符串拼接方法,避免重复代码 + private static String buildExpression(List tokens) { + StringBuilder sb = new StringBuilder(); + for (String tk : tokens) sb.append(tk); + sb.append(" ="); + return sb.toString(); + } + + // 通用的基础表达式生成逻辑 + private static List generateBaseExpression(int minOperands, int maxOperands, String operators) { + int operands = minOperands + RANDOM.nextInt(maxOperands - minOperands + 1); List tokens = new ArrayList<>(); - int first = 1 + RANDOM.nextInt(100); + int first = MIN_OPERAND_VALUE + RANDOM.nextInt(MAX_OPERAND_VALUE); tokens.add(String.valueOf(first)); for (int i = 1; i < operands; i++) { - char op = pickOperator("+*/"); - int n = 1 + RANDOM.nextInt(100); + char op = pickOperator(operators); + int n = MIN_OPERAND_VALUE + RANDOM.nextInt(MAX_OPERAND_VALUE); if (op == '/') { - // 让被除数尽可能能整除,依据上一个纯数字令除数为其因子 int prevNumber = extractLastPureNumber(tokens); if (prevNumber > 0) { n = pickDivisor(prevNumber); @@ -184,73 +199,63 @@ public class Main { tokens.add(" " + op + " "); tokens.add(String.valueOf(n)); } - maybeInsertParentheses(tokens); - StringBuilder sb = new StringBuilder(); - for (String tk : tokens) sb.append(tk); - return sb.toString(); + return tokens; } - private static String generateJunior() { - // 至少包含一个 平方 或 开根号;允许 + - * / 和括号 - int operands = 2 + RANDOM.nextInt(4); // 2-5 - List tokens = new ArrayList<>(); - String first = String.valueOf(1 + RANDOM.nextInt(100)); - tokens.add(first); - for (int i = 1; i < operands; i++) { - char op = pickOperator("+-*/"); - String n = String.valueOf(1 + RANDOM.nextInt(100)); - tokens.add(" " + op + " "); - tokens.add(n); + static class PrimaryQuestionGenerator implements QuestionGenerator { + @Override + public String generate() { + List tokens = generateBaseExpression(2, 5, "+*/"); + maybeInsertParentheses(tokens); + return buildExpression(tokens); } - // 强制至少包含一个 平方 或 根号 - ensureJuniorFeature(tokens); - maybeInsertParentheses(tokens); - StringBuilder sb = new StringBuilder(); - for (String tk : tokens) sb.append(tk); - return sb.toString(); } - private static String generateSenior() { - // 至少包含一个 sin/cos/tan;允许 + - * / 和括号 - int operands = 3 + RANDOM.nextInt(3); // 3-5 - List tokens = new ArrayList<>(); - tokens.add(String.valueOf(1 + RANDOM.nextInt(100))); - for (int i = 1; i < operands; i++) { - char op = pickOperator("+-*/"); - String n = String.valueOf(1 + RANDOM.nextInt(100)); - tokens.add(" " + op + " "); - tokens.add(n); + static class JuniorQuestionGenerator implements QuestionGenerator { + @Override + public String generate() { + List tokens = generateBaseExpression(2, 5, "+-*/"); + ensureJuniorFeature(tokens); + maybeInsertParentheses(tokens); + return buildExpression(tokens); } - ensureSeniorFeature(tokens); - maybeInsertParentheses(tokens); - StringBuilder sb = new StringBuilder(); - for (String tk : tokens) sb.append(tk); - return sb.toString(); } + static class SeniorQuestionGenerator implements QuestionGenerator { + @Override + public String generate() { + List tokens = generateBaseExpression(3, 5, "+-*/"); + ensureSeniorFeature(tokens); + maybeInsertParentheses(tokens); + return buildExpression(tokens); + } + } + + private static final Map GENERATOR_MAP = new EnumMap<>(Level.class); + static { + GENERATOR_MAP.put(Level.小学, new PrimaryQuestionGenerator()); + GENERATOR_MAP.put(Level.初中, new JuniorQuestionGenerator()); + GENERATOR_MAP.put(Level.高中, new SeniorQuestionGenerator()); + } + + private static String generateQuestion(Level level) { + QuestionGenerator generator = GENERATOR_MAP.get(level); + if (generator == null) generator = GENERATOR_MAP.get(Level.小学); + return generator.generate(); + } + + // 生成器实现已迁移到各具体类 + private static char pickOperator(String candidates) { int idx = RANDOM.nextInt(candidates.length()); return candidates.charAt(idx); } - private static int lastNumberForDivision(CharSequence currentExpr) { - // 粗略解析,找到最后一个数字(用于生成可整除的除法) - int i = currentExpr.length() - 1; - while (i >= 0 && !Character.isDigit(currentExpr.charAt(i))) i--; - int end = i; - while (i >= 0 && Character.isDigit(currentExpr.charAt(i))) i--; - int start = i + 1; - if (start <= end) { - return Integer.parseInt(currentExpr.subSequence(start, end + 1).toString()); - } - return 1 + RANDOM.nextInt(100); - } - private static int pickDivisor(int dividend) { dividend = Math.abs(dividend); if (dividend == 0) return 1; List divisors = new ArrayList<>(); - for (int d = 1; d <= Math.min(dividend, 100); d++) { + for (int d = 1; d <= Math.min(dividend, MAX_OPERAND_VALUE); d++) { if (dividend % d == 0) { divisors.add(d); } @@ -258,21 +263,7 @@ public class Main { return divisors.get(RANDOM.nextInt(divisors.size())); } - private static String buildExpressionWithParentheses(List numbers, List ops) { - // 已不再使用该构造器于主流程,保留供兼容 - List tokens = new ArrayList<>(); - tokens.add(String.valueOf(numbers.get(0))); - for (int i = 0; i < ops.size(); i++) { - char op = ops.get(i); - int n = numbers.get(i + 1); - tokens.add(" " + op + " "); - tokens.add(String.valueOf(n)); - } - maybeInsertParentheses(tokens); - StringBuilder sb = new StringBuilder(); - for (String tk : tokens) sb.append(tk); - return sb.toString(); - } + private static void maybeInsertParentheses(List tokens) { int parenCount = RANDOM.nextInt(3); // 0,1,2 对 @@ -353,7 +344,8 @@ public class Main { File[] files = folder.listFiles((dir, name) -> name.endsWith(".txt")); if (files == null) return set; for (File f : files) { - try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8))) { + try (BufferedReader br = new BufferedReader( + new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8))) { String line; while ((line = br.readLine()) != null) { line = line.trim();