Compare commits

...

1 Commits

@ -1,6 +1,7 @@
# 程序运行说明
1. 环境配置java21及以上不推荐使用windows要设置更改字符否则中文字符会乱码建议使用ubuntumacos等系统
2. 在控制台输入
```bash
@ -8,5 +9,10 @@
```
可以开始使用程序
3. 程序提供在windows运行的bat脚本需要可以双击运行
4. 注册功能的说明:注册功能是自己添加,由于项目要求登录时将用户名和密码同行隔空格输入,因此注册时的特殊情况,如密码含空格,会无法登录,但是登录不是课程考核之一,希望不要引起不必要的误会,特此说明
4. 第一次运行时在运行目录下会生成默认用户的json文件生成的试卷放在generated文件夹下
5. 注册功能的说明:注册功能是自己添加,由于项目要求登录时将用户名和密码同行隔空格输入,因此注册时的特殊情况,如密码含空格,会无法登录,但是登录不是课程考核之一,希望不要引起不必要的误会,特此说明

@ -0,0 +1,124 @@
package com.mathgenerator.generator;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
/**
*
* ()
*/
public class SafePrimarySchoolGenerator implements QuestionGenerator {
/**
* 2-5
* @return
*/
@Override
public String generateSingleQuestion() {
int operandsTotalBudget = ThreadLocalRandom.current().nextInt(2, 6);
Term finalExpression = generateSafeExpression(operandsTotalBudget);
return String.join(" ", finalExpression.parts);
}
/**
*
*
* @param operandBudget
* @return Term
*/
private Term generateSafeExpression(int operandBudget) {
ThreadLocalRandom random = ThreadLocalRandom.current();
List<String> fullExpressionParts = new ArrayList<>();
int operandsRemaining = operandBudget;
// 1. 生成第一个项
Term firstTerm = generateTerm(operandsRemaining);
fullExpressionParts.addAll(firstTerm.parts);
int currentResult = firstTerm.value;
operandsRemaining -= firstTerm.operandsUsed;
// 2. 循环生成后续的项,直到预算用完
while (operandsRemaining > 0) {
Term nextTerm = generateTerm(operandsRemaining);
boolean useAddition = random.nextBoolean();
if (!useAddition && currentResult < nextTerm.value) {
useAddition = true; // 强制改为加法以避免负数
}
if (useAddition) {
fullExpressionParts.add("+");
currentResult += nextTerm.value;
} else {
fullExpressionParts.add("-");
currentResult -= nextTerm.value;
}
fullExpressionParts.addAll(nextTerm.parts);
operandsRemaining -= nextTerm.operandsUsed;
}
return new Term(fullExpressionParts, currentResult, operandBudget - operandsRemaining);
}
/**
* (Term)
*
*/
private Term generateTerm(int operandsRemaining) {
ThreadLocalRandom random = ThreadLocalRandom.current();
// 如果预算充足(>=2且随机命中则生成带括号的复杂项
if (operandsRemaining >= 2 && random.nextInt(10) < 3) { // 30%的概率生成括号
// 为括号内的子表达式分配预算至少2个最多为剩余预算
int subExpressionBudget = random.nextInt(2, operandsRemaining + 1);
Term subExpression = generateSafeExpression(subExpressionBudget);
List<String> parts = new ArrayList<>();
parts.add("(");
parts.addAll(subExpression.parts);
parts.add(")");
return new Term(parts, subExpression.value, subExpression.operandsUsed);
} else {
// 否则,生成简单的乘除法项
return generateSimpleTerm(operandsRemaining);
}
}
/**
*
*/
private Term generateSimpleTerm(int operandsRemaining) {
ThreadLocalRandom random = ThreadLocalRandom.current();
List<String> parts = new ArrayList<>();
int termValue = random.nextInt(1, 21);
parts.add(String.valueOf(termValue));
int operandsUsed = 1;
if (operandsRemaining > 1 && random.nextBoolean()) {
if (random.nextBoolean()) {
parts.add("*");
int multiplier = random.nextInt(1, 10);
parts.add(String.valueOf(multiplier));
termValue *= multiplier;
} else {
parts.add("/");
List<Integer> divisors = getDivisors(termValue);
int divisor = divisors.get(random.nextInt(divisors.size()));
parts.add(String.valueOf(divisor));
termValue /= divisor;
}
operandsUsed++;
}
return new Term(parts, termValue, operandsUsed);
}
private record Term(List<String> parts, int value, int operandsUsed) {}
private List<Integer> getDivisors(int number) {
List<Integer> divisors = new ArrayList<>();
for (int i = 1; i <= number; i++) {
if (number % i == 0) divisors.add(i);
}
return divisors;
}
}

@ -6,12 +6,12 @@ import java.util.concurrent.ThreadLocalRandom;
/**
*
* <p>
*
* ()
*/
public class MixedDifficultyStrategy implements PaperStrategy {
// 策略内部持有所有可能的生成器
// 持有所有可能的生成器
private final QuestionGenerator primaryGenerator = new PrimarySchoolGenerator();
private final QuestionGenerator safePrimaryGenerator = new SafePrimarySchoolGenerator(); // 新增
private final QuestionGenerator juniorHighGenerator = new JuniorHighSchoolGenerator();
private final QuestionGenerator seniorHighGenerator = new SeniorHighSchoolGenerator();
@ -20,14 +20,15 @@ public class MixedDifficultyStrategy implements PaperStrategy {
double randomValue = ThreadLocalRandom.current().nextDouble();
return switch (mainLevel) {
case PRIMARY -> primaryGenerator;
// 当主难度是小学时100%使用“安全”的生成器
case PRIMARY -> safePrimaryGenerator;
case JUNIOR_HIGH -> {
// 初中试卷70%初中难度30%小学难度
// 初中试卷70%初中难度30%使用“不安全”的小学难度(允许负数)
if (randomValue < 0.7) yield juniorHighGenerator;
else yield primaryGenerator;
}
case SENIOR_HIGH -> {
// 高中试卷60%高中难度30%初中难度10%小学难度
// 高中试卷60%高中30%初中10%使用“不安全”的小学难度
if (randomValue < 0.6) yield seniorHighGenerator;
else if (randomValue < 0.9) yield juniorHighGenerator;
else yield primaryGenerator;

Loading…
Cancel
Save