diff --git a/src/PowerManager.java b/src/PowerManager.java new file mode 100644 index 0000000..b3ba370 --- /dev/null +++ b/src/PowerManager.java @@ -0,0 +1,95 @@ +import java.util.List; +import java.util.Random; + +/** + * 负责添加幂运算 + */ +public class PowerManager { + private static final Random RANDOM = new Random(); + + // 普通幂运算 + public String addPowerOperations(String expression, List numPositions) { + if (numPositions.isEmpty()) return expression; + + String[] tokens = expression.split(" "); + int targetIndex = chooseTargetIndex(tokens, numPositions, null); + + if (targetIndex != -1) { + tokens[targetIndex] = applyPower(tokens[targetIndex], tokens, targetIndex); + } + + return String.join(" ", tokens); + } + + // 避免加在 trig 已占用的位置,同时避免加在运算符右边 + public String addPowerOperationsAvoid(String expression, List numPositions, List trigPositions) { + if (numPositions.isEmpty()) return expression; + + String[] tokens = expression.split(" "); + int targetIndex = chooseTargetIndex(tokens, numPositions, trigPositions); + + if (targetIndex != -1) { + tokens[targetIndex] = applyPower(tokens[targetIndex], tokens, targetIndex); + } + + return String.join(" ", tokens); + } + + // 选择合适的位置加幂运算 + private int chooseTargetIndex(String[] tokens, List numPositions, List avoidPositions) { + for (int tries = 0; tries < 20; tries++) { + int idx = numPositions.get(RANDOM.nextInt(numPositions.size())); + + if ((avoidPositions == null || !avoidPositions.contains(idx)) && canApplyPower(tokens, idx)) { + return idx; + } + } + return -1; + } + + // 检查该位置是否可以加幂运算 + private boolean canApplyPower(String[] tokens, int index) { + if (!isNumber(tokens[index])) return false; + if (tokens[index].contains("^") || tokens[index].contains("√")) return false; // 避免重复幂运算 + + // 不能加在运算符右边 + if (index > 0) { + String prev = tokens[index - 1]; + if (prev.equals("/") || prev.equals("*") || prev.equals("+") || prev.equals("-")) { + return false; + } + } + return true; + } + + // 应用平方或开方(根号放左括号左侧,平方放右括号右侧) + private String applyPower(String token, String[] tokens, int index) { + boolean useSqrt = RANDOM.nextBoolean(); + + if (useSqrt) { + // 根号放在左括号左侧,如果前面是左括号,则放在括号左边 + if (index > 0 && tokens[index - 1].equals(")")) { + return "√" + token; // 特殊情况,仍然放数字前 + } + if (index > 0 && tokens[index - 1].equals("(")) { + return "√" + token; + } + return "√" + token; + } else { + // 平方放在右括号右侧,如果后面是右括号,则放在括号右边 + if (index < tokens.length - 1 && tokens[index + 1].equals(")")) { + return token + "^2"; + } + return token + "^2"; + } + } + + private boolean isNumber(String token) { + try { + Integer.parseInt(token); + return true; + } catch (NumberFormatException e) { + return false; + } + } +}