import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Random; import java.util.Set; /** * 抽象题目生成器(模板方法模式)。 * 实现了 IProblemGenerator 接口,提供了通用的题目生成逻辑, * 如唯一性检查循环、操作数生成等,将具体的题目构建逻辑延迟到子类。 */ public abstract class AbstractProblemGenerator implements IProblemGenerator { protected final Random random = new Random(); protected static final int MIN_OPERAND_VALUE = 1; protected static final int MAX_OPERAND_VALUE = 100; protected static final int MIN_OPERANDS_COUNT = 2; protected static final int MAX_OPERANDS_COUNT = 5; @Override public List generate(int count, Set existingProblems) { List newProblems = new ArrayList<>(count); // 使用一个临时的Set来防止在同一次生成任务中产生重复 Set currentBatchSet = new HashSet<>(); while (newProblems.size() < count) { Equation candidate = createProblem(); String canonicalForm = candidate.toCanonicalString(); // 执行唯一性检查:既不能与历史重复,也不能与本次生成的其他题目重复 if (!existingProblems.contains(canonicalForm) && !currentBatchSet.contains(canonicalForm)) { newProblems.add(candidate); currentBatchSet.add(canonicalForm); } } return newProblems; } /** * 创建一个候选数学题目的抽象方法(模板方法)。 * 子类必须实现此方法来定义具体难度的题目生成规则。 * * @return 一个新创建的 Equation 对象 */ protected abstract Equation createProblem(); /** * 生成一个在指定范围内的随机整数。 * * @param min 最小值(包含) * @param max 最大值(包含) * @return 随机整数 */ protected int getRandomNumber(int min, int max) { return random.nextInt(max - min + 1) + min; } /** * 从给定的操作符数组中随机选择一个。 * @param availableOperators 可用的操作符数组 * @return 随机选择的操作符 */ protected Operator getRandomOperator(Operator[] availableOperators) { return availableOperators[random.nextInt(availableOperators.length)]; } }