You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
2.3 KiB
67 lines
2.3 KiB
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<Equation> generate(int count, Set<String> existingProblems) {
|
|
List<Equation> newProblems = new ArrayList<>(count);
|
|
// 使用一个临时的Set来防止在同一次生成任务中产生重复
|
|
Set<String> 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)];
|
|
}
|
|
} |