From 16ae5713e34be24d185d2f98f83f346edaa36234 Mon Sep 17 00:00:00 2001 From: hnu202326010305 <1405671544@qq.com> Date: Sun, 28 Sep 2025 00:54:33 +0800 Subject: [PATCH] ADD file via upload --- src/BracketManager.java | 148 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 src/BracketManager.java diff --git a/src/BracketManager.java b/src/BracketManager.java new file mode 100644 index 0000000..ce53f57 --- /dev/null +++ b/src/BracketManager.java @@ -0,0 +1,148 @@ +import java.util.List; +import java.util.Random; + +/** + * 负责生成并添加括号 + */ +public class BracketManager { + private static final Random RANDOM = new Random(); + + /** + * 根据元素个数选择括号对数 + * 3 -> 80% 1对 20%0对 + * 4 -> 90% 1对 10%2对 + * 5 -> 50% 1对 50%2对 + */ + public int decideParenthesesPairs(int numCount) { + return switch (numCount) { + case 3 -> RANDOM.nextDouble() < 0.8 ? 1 : 0; + case 4 -> RANDOM.nextDouble() < 0.9 ? 1 : 2; + case 5 -> RANDOM.nextDouble() < 0.5 ? 1 : 2; + default -> 0; + }; + } + + // 添加括号 + public String addParentheses(String expression, int pairs, List numPositions) { + String[] tokens = expression.split(" "); + int numCount = numPositions.size(); + boolean[] markLeft = new boolean[numCount]; + boolean[] markRight = new boolean[numCount]; + + generateBracketPositions(numCount, numPositions, pairs, tokens, markLeft, markRight); + String result = insertBrackets(tokens, markLeft, markRight); + return validateParentheses(result) ? result : expression; + } + + //计算生成括号的位置 + private void generateBracketPositions(int numCount, List numPositions, int pairs, String[] tokens, + boolean[] markLeft, boolean[] markRight) { + int attempts = 0; + for (int p = 0; p < pairs && attempts < 50; p++, attempts++) { + boolean placed = false; + for (int tries = 0; tries < 50 && !placed; tries++) { + int start = RANDOM.nextInt(numCount - 1); + int end = start + 1 + RANDOM.nextInt(numCount - start - 1); + if (end >= numCount) end = numCount - 1; + + // 20%概率尝试嵌套在已有括号内部 + if (RANDOM.nextDouble() < 0.2) { + for (int i = 0; i < numCount; i++) { + if (markLeft[i]) { + start = i; + end = i + RANDOM.nextInt(numCount - i); + break; + } + } + } + + if (canPlaceBracket(start, end, markLeft, markRight, numPositions, tokens)) { + markLeft[start] = true; + markRight[end] = true; + placed = true; + } + } + } + } + + //检测添加括号的合法性 + private boolean canPlaceBracket(int start, int end, boolean[] markLeft, boolean[] markRight, + List numPositions, String[] tokens) { + if (isOuterMostBracket(start, end, markLeft.length)) return false; + if (isInvalidOverlap(start, end, markLeft, markRight)) return false; + return isValidBracketRange(tokens, numPositions, start, end); + } + + //避免最外层括号 + private boolean isOuterMostBracket(int start, int end, int numCount) { + return start == 0 && end == numCount - 1; + } + + //允许嵌套但禁止交叉 + private boolean isInvalidOverlap(int start, int end, boolean[] markLeft, boolean[] markRight) { + for (int i = start; i <= end; i++) { + // start/end可重合,内部禁止已有左右括号 + if ((i != start && markLeft[i]) || (i != end && markRight[i])) return true; + } + return false; + } + + //检测括号是否有意义(优先级) + private boolean isValidBracketRange(String[] tokens, List numPositions, int start, int end) { + int opStart = numPositions.get(start) + 1; + int opEnd = numPositions.get(end) - 1; + String firstOp = null; + boolean hasHigherOuterOp = false; + + for (int i = opStart; i <= opEnd; i += 2) { + if (!isNumber(tokens[i])) { + if (firstOp == null) firstOp = tokens[i]; + else if (isDifferentPriority(firstOp, tokens[i])) { + hasHigherOuterOp = true; + break; + } + } + } + return hasHigherOuterOp || firstOp == null; + } + + //比较运算符优先级 + private boolean isDifferentPriority(String op1, String op2) { + int p1 = (op1.equals("+") || op1.equals("-")) ? 1 : 2; + int p2 = (op2.equals("+") || op2.equals("-")) ? 1 : 2; + return p1 != p2; + } + + //插入操作 + private String insertBrackets(String[] tokens, boolean[] markLeft, boolean[] markRight) { + StringBuilder sb = new StringBuilder(); + int numIndex = 0; + for (String token : tokens) { + if (isNumber(token)) { + if (markLeft[numIndex]) sb.append("( "); + sb.append(token); + if (markRight[numIndex]) sb.append(" )"); + numIndex++; + } else { + sb.append(" ").append(token).append(" "); + } + } + return sb.toString(); + } + + //检查括号是否缺失 + private boolean validateParentheses(String expr) { + int balance = 0; + for (char c : expr.toCharArray()) { + if (c == '(') balance++; + if (c == ')') balance--; + if (balance < 0) return false; + } + return balance == 0; + } + + private boolean isNumber(String token) { + try { Integer.parseInt(token); return true; } + catch (NumberFormatException e) { return false; } + } +}