Compare commits
2 Commits
563e4f0404
...
3f970c05ce
Author | SHA1 | Date |
---|---|---|
|
3f970c05ce | 1 week ago |
|
9243537004 | 1 week ago |
@ -0,0 +1,52 @@
|
||||
package com.mathpaper.question;
|
||||
|
||||
import com.mathpaper.util.Utils;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class JuniorQuestionGenerator implements QuestionGenerator {
|
||||
private final QuestionChecker checker = new QuestionChecker();
|
||||
private final Random RANDOM = new Random();
|
||||
|
||||
@Override
|
||||
public List<String> generate(int count, String username) {
|
||||
List<String> questions = new ArrayList<>();
|
||||
while (questions.size() < count) {
|
||||
String expr = generateSingle();
|
||||
if (!checker.isDuplicate(username, expr)) {
|
||||
questions.add((questions.size() + 1) + ". " + expr + " = ");
|
||||
}
|
||||
}
|
||||
return questions;
|
||||
}
|
||||
|
||||
// 生成一道初中题(确保含平方/开根号)
|
||||
private String generateSingle() {
|
||||
String expr = "";
|
||||
do {
|
||||
int operandCount = Utils.getOperandCount();
|
||||
StringBuilder exprBuilder = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < operandCount; i++) {
|
||||
int num = Utils.getRandomOperand();
|
||||
String operand;
|
||||
|
||||
// 30%概率将操作数改为平方或开根号
|
||||
if (RANDOM.nextDouble() < 0.3) {
|
||||
operand = RANDOM.nextBoolean() ? Utils.getSquare(String.valueOf(num)) : Utils.getSqrt(String.valueOf(num));
|
||||
} else {
|
||||
operand = String.valueOf(num);
|
||||
}
|
||||
|
||||
exprBuilder.append(operand);
|
||||
if (i < operandCount - 1) {
|
||||
exprBuilder.append(" ").append(Utils.getPrimaryOp()).append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
expr = Utils.addBrackets(exprBuilder.toString());
|
||||
} while (!Utils.isJuniorValid(expr)); // 校验难度
|
||||
return expr;
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.mathpaper.user;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AccountManager {
|
||||
// 预设账号列表(静态初始化,程序启动时加载)
|
||||
private static final List<Account> ACCOUNTS;
|
||||
|
||||
static {
|
||||
ACCOUNTS = new ArrayList<>();
|
||||
// 小学账号
|
||||
ACCOUNTS.add(new Account("张三1", "123", "小学"));
|
||||
ACCOUNTS.add(new Account("张三2", "123", "小学"));
|
||||
ACCOUNTS.add(new Account("张三3", "123", "小学"));
|
||||
// 初中账号
|
||||
ACCOUNTS.add(new Account("李四1", "123", "初中"));
|
||||
ACCOUNTS.add(new Account("李四2", "123", "初中"));
|
||||
ACCOUNTS.add(new Account("李四3", "123", "初中"));
|
||||
// 高中账号
|
||||
ACCOUNTS.add(new Account("王五1", "123", "高中"));
|
||||
ACCOUNTS.add(new Account("王五2", "123", "高中"));
|
||||
ACCOUNTS.add(new Account("王五3", "123", "高中"));
|
||||
}
|
||||
|
||||
// 验证用户名和密码是否正确
|
||||
public static boolean validate(String username, String password) {
|
||||
for (Account acc : ACCOUNTS) {
|
||||
if (acc.getUsername().equals(username) && acc.getPassword().equals(password)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 根据用户名获取学段(登录验证通过后调用)
|
||||
public static String getAccountType(String username) {
|
||||
for (Account acc : ACCOUNTS) {
|
||||
if (acc.getUsername().equals(username)) {
|
||||
return acc.getType();
|
||||
}
|
||||
}
|
||||
return null; // 理论上不会触发(已验证账号)
|
||||
}
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
package com.mathpaper.util;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Utils {
|
||||
private static final Random RANDOM = new Random();
|
||||
private static final String[] PRIMARY_OPS = {"+", "-", "*", "/"};
|
||||
private static final String[] TRIG_FUNCS = {"sin", "cos", "tan"};
|
||||
private static final Pattern SUB_EXPR_PATTERN = Pattern.compile("\\d+\\s[+\\-*/]\\s\\d+");
|
||||
|
||||
// 生成1-100的随机操作数
|
||||
public static int getRandomOperand() {
|
||||
return RANDOM.nextInt(100) + 1;
|
||||
}
|
||||
|
||||
// 生成2-5个操作数
|
||||
public static int getOperandCount() {
|
||||
return RANDOM.nextInt(4) + 2;
|
||||
}
|
||||
|
||||
// 生成小学随机运算符
|
||||
public static String getPrimaryOp() {
|
||||
return PRIMARY_OPS[RANDOM.nextInt(PRIMARY_OPS.length)];
|
||||
}
|
||||
|
||||
// 生成三角函数
|
||||
public static String getTrigFunc() {
|
||||
String func = TRIG_FUNCS[RANDOM.nextInt(TRIG_FUNCS.length)];
|
||||
int angle = RANDOM.nextInt(181);
|
||||
return func + "(" + angle + ")°";
|
||||
}
|
||||
|
||||
// 生成平方
|
||||
public static String getSquare(String num) {
|
||||
return num + "\u00B2";
|
||||
}
|
||||
|
||||
// 生成开根号
|
||||
public static String getSqrt(String num) {
|
||||
return "√(" + num + ")";
|
||||
}
|
||||
|
||||
// 添加括号(拆分后主方法)
|
||||
public static String addBrackets(String expr) {
|
||||
if (!shouldAddBrackets(expr)) return expr;
|
||||
Matcher matcher = SUB_EXPR_PATTERN.matcher(expr);
|
||||
int[] positions = findValidSubExpression(matcher, expr);
|
||||
return positions[0] == -1 ? expr : wrapSubExpression(expr, positions);
|
||||
}
|
||||
|
||||
// 辅助:判断是否需要添加括号
|
||||
private static boolean shouldAddBrackets(String expr) {
|
||||
return expr.length() >= 5 && countOperands(expr) >= 3 && RANDOM.nextBoolean();
|
||||
}
|
||||
|
||||
// 辅助:查找合法的子表达式位置
|
||||
private static int[] findValidSubExpression(Matcher matcher, String expr) {
|
||||
int[] positions = {-1, -1};
|
||||
while (matcher.find()) {
|
||||
if (matcher.start() > 0 || matcher.end() < expr.length() - 1) {
|
||||
positions[0] = matcher.start();
|
||||
positions[1] = matcher.end();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return positions;
|
||||
}
|
||||
|
||||
// 辅助:用括号包裹子表达式
|
||||
private static String wrapSubExpression(String expr, int[] positions) {
|
||||
return expr.substring(0, positions[0]) + "(" +
|
||||
expr.substring(positions[0], positions[1]) + ")" +
|
||||
expr.substring(positions[1]);
|
||||
}
|
||||
|
||||
// 统计操作数数量
|
||||
private static int countOperands(String expr) {
|
||||
return expr.split("\\s[+\\-*/]\\s").length;
|
||||
}
|
||||
|
||||
// 校验初中题目
|
||||
public static boolean isJuniorValid(String expr) {
|
||||
return expr.contains("\u00B2") || expr.contains("√");
|
||||
}
|
||||
|
||||
// 校验高中题目
|
||||
public static boolean isSeniorValid(String expr) {
|
||||
return expr.contains("sin") || expr.contains("cos") || expr.contains("tan");
|
||||
}
|
||||
|
||||
// 验证表达式合法性
|
||||
public static boolean isValidExpression(String expr) {
|
||||
return hasValidOperator(expr) && !hasConsecutiveOperators(expr) && hasMatchingBrackets(expr);
|
||||
}
|
||||
|
||||
// 辅助:检查是否包含至少一个运算符
|
||||
private static boolean hasValidOperator(String expr) {
|
||||
return expr.matches(".*[+\\-*/].*");
|
||||
}
|
||||
|
||||
// 辅助:检查是否有连续运算符
|
||||
private static boolean hasConsecutiveOperators(String expr) {
|
||||
return expr.matches(".*[+\\-*/]\\s*[+\\-*/].*");
|
||||
}
|
||||
|
||||
// 辅助:检查括号是否匹配
|
||||
private static boolean hasMatchingBrackets(String expr) {
|
||||
int bracketCount = 0;
|
||||
for (char c : expr.toCharArray()) {
|
||||
if (c == '(') bracketCount++;
|
||||
else if (c == ')') bracketCount--;
|
||||
if (bracketCount < 0) return false;
|
||||
}
|
||||
return bracketCount == 0;
|
||||
}
|
||||
}
|
Loading…
Reference in new issue