Merge pull request '4' (#4) from develop into main
commit
589993dca5
@ -1,95 +1,148 @@
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Random;
|
||||||
/**
|
|
||||||
* 负责添加幂运算
|
public class PowerManager {
|
||||||
*/
|
private static final Random RANDOM = new Random();
|
||||||
public class PowerManager {
|
|
||||||
private static final Random RANDOM = new Random();
|
//添加一次幂运算,30%概率再加一次
|
||||||
|
public String addPowerOperations(String expression, List<Integer> numPositions,
|
||||||
// 普通幂运算
|
List<Integer> trigPositions) {
|
||||||
public String addPowerOperations(String expression, List<Integer> numPositions) {
|
if (numPositions.isEmpty()) {
|
||||||
if (numPositions.isEmpty()) return expression;
|
return expression;
|
||||||
|
}
|
||||||
String[] tokens = expression.split(" ");
|
|
||||||
int targetIndex = chooseTargetIndex(tokens, numPositions, null);
|
String[] tokens = expression.split(" ");
|
||||||
|
|
||||||
if (targetIndex != -1) {
|
addOnePower(tokens, numPositions, trigPositions);
|
||||||
tokens[targetIndex] = applyPower(tokens[targetIndex], tokens, targetIndex);
|
if (RANDOM.nextDouble() < 0.3) {
|
||||||
}
|
addOnePower(tokens, numPositions, trigPositions);
|
||||||
|
}
|
||||||
return String.join(" ", tokens);
|
|
||||||
}
|
return String.join(" ", tokens);
|
||||||
|
}
|
||||||
// 避免加在 trig 已占用的位置,同时避免加在运算符右边
|
|
||||||
public String addPowerOperationsAvoid(String expression, List<Integer> numPositions, List<Integer> trigPositions) {
|
// 添加一次幂运算,平方/根号各50%
|
||||||
if (numPositions.isEmpty()) return expression;
|
private void addOnePower(String[] tokens, List<Integer> numPositions, List<Integer> trigPositions) {
|
||||||
|
if (RANDOM.nextBoolean()) {
|
||||||
String[] tokens = expression.split(" ");
|
tryAddSquare(tokens, numPositions, trigPositions);
|
||||||
int targetIndex = chooseTargetIndex(tokens, numPositions, trigPositions);
|
} else {
|
||||||
|
tryAddSqrt(tokens, numPositions, trigPositions);
|
||||||
if (targetIndex != -1) {
|
}
|
||||||
tokens[targetIndex] = applyPower(tokens[targetIndex], tokens, targetIndex);
|
}
|
||||||
}
|
|
||||||
|
// 添加平方
|
||||||
return String.join(" ", tokens);
|
private void tryAddSquare(String[] tokens, List<Integer> numPositions,
|
||||||
}
|
List<Integer> trigPositions) {
|
||||||
|
int target = chooseTargetIndex(tokens, numPositions, trigPositions, true);
|
||||||
// 选择合适的位置加幂运算
|
if (target != -1) {
|
||||||
private int chooseTargetIndex(String[] tokens, List<Integer> numPositions, List<Integer> avoidPositions) {
|
tokens[target] = tokens[target] + "^2";
|
||||||
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;
|
private void tryAddSqrt(String[] tokens, List<Integer> numPositions,
|
||||||
}
|
List<Integer> trigPositions) {
|
||||||
}
|
int target = chooseTargetIndex(tokens, numPositions, trigPositions, false);
|
||||||
return -1;
|
if (target != -1) {
|
||||||
}
|
tokens[target] = "√" + tokens[target];
|
||||||
|
}
|
||||||
// 检查该位置是否可以加幂运算
|
}
|
||||||
private boolean canApplyPower(String[] tokens, int index) {
|
|
||||||
if (!isNumber(tokens[index])) return false;
|
// 选择可插入位置
|
||||||
if (tokens[index].contains("^") || tokens[index].contains("√")) return false; // 避免重复幂运算
|
private int chooseTargetIndex(String[] tokens, List<Integer> numPositions,
|
||||||
|
List<Integer> trigPositions, boolean isSquare) {
|
||||||
// 不能加在运算符右边
|
List<Integer> candidates = new ArrayList<>();
|
||||||
if (index > 0) {
|
for (int idx : numPositions) {
|
||||||
String prev = tokens[index - 1];
|
String token = tokens[idx];
|
||||||
if (prev.equals("/") || prev.equals("*") || prev.equals("+") || prev.equals("-")) {
|
|
||||||
return false;
|
// 避免 trig 位置
|
||||||
}
|
if (trigPositions != null && trigPositions.contains(idx)) {
|
||||||
}
|
continue;
|
||||||
return true;
|
}
|
||||||
}
|
// 不能已有运算
|
||||||
|
if (token.contains("^") || token.contains("√")) {
|
||||||
// 应用平方或开方(根号放左括号左侧,平方放右括号右侧)
|
continue;
|
||||||
private String applyPower(String token, String[] tokens, int index) {
|
}
|
||||||
boolean useSqrt = RANDOM.nextBoolean();
|
// 括号匹配检查
|
||||||
|
if ((token.equals("(") || token.equals(")")) && !checkParenCanAdd(tokens, idx, isSquare)) {
|
||||||
if (useSqrt) {
|
continue;
|
||||||
// 根号放在左括号左侧,如果前面是左括号,则放在括号左边
|
}
|
||||||
if (index > 0 && tokens[index - 1].equals(")")) {
|
|
||||||
return "√" + token; // 特殊情况,仍然放数字前
|
// 根号/平方合法性
|
||||||
}
|
if (isSquare) {
|
||||||
if (index > 0 && tokens[index - 1].equals("(")) {
|
if (isNumber(token) || token.equals(")")) {
|
||||||
return "√" + token;
|
candidates.add(idx);
|
||||||
}
|
}
|
||||||
return "√" + token;
|
}
|
||||||
} else {
|
if (!isSquare) {
|
||||||
// 平方放在右括号右侧,如果后面是右括号,则放在括号右边
|
if (isNumber(token) || token.equals("(")) {
|
||||||
if (index < tokens.length - 1 && tokens[index + 1].equals(")")) {
|
candidates.add(idx);
|
||||||
return token + "^2";
|
}
|
||||||
}
|
}
|
||||||
return token + "^2";
|
}
|
||||||
}
|
|
||||||
}
|
if (candidates.isEmpty()) {
|
||||||
|
return -1;
|
||||||
private boolean isNumber(String token) {
|
}
|
||||||
try {
|
return candidates.get(RANDOM.nextInt(candidates.size()));
|
||||||
Integer.parseInt(token);
|
}
|
||||||
return true;
|
|
||||||
} catch (NumberFormatException e) {
|
// 检查括号匹配另一侧是否可以加运算
|
||||||
return false;
|
private boolean checkParenCanAdd(String[] tokens, int index, boolean isSquare) {
|
||||||
}
|
int match = findMatchingParen(tokens, index);
|
||||||
}
|
if (match == -1) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查匹配括号是否已加运算
|
||||||
|
if (tokens[match].contains("^") || tokens[match].contains("√")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 左括号只能加根号,右括号只能加平方
|
||||||
|
if (isSquare && tokens[index].equals("(")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return isSquare || !tokens[index].equals(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 找匹配括号
|
||||||
|
private int findMatchingParen(String[] tokens, int index) {
|
||||||
|
if (tokens[index].equals("(")) {
|
||||||
|
int depth = 0;
|
||||||
|
for (int i = index; i < tokens.length; i++) {
|
||||||
|
if (tokens[i].equals("(")) {
|
||||||
|
depth++;
|
||||||
|
} else if (tokens[i].equals(")")) {
|
||||||
|
depth--;
|
||||||
|
if (depth == 0) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (tokens[index].equals(")")) {
|
||||||
|
int depth = 0;
|
||||||
|
for (int i = index; i >= 0; i--) {
|
||||||
|
if (tokens[i].equals(")")) {
|
||||||
|
depth++;
|
||||||
|
} else if (tokens[i].equals("(")) {
|
||||||
|
depth--;
|
||||||
|
if (depth == 0) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNumber(String token) {
|
||||||
|
try {
|
||||||
|
Integer.parseInt(token);
|
||||||
|
return true;
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in new issue