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; } } }