解决切换问题

develop
tianyuan 7 days ago
parent 675c7906a4
commit 9eaadbc1d0

@ -0,0 +1,37 @@
import java.util.List;
/**
*
*/
public abstract class AbstractMathGenerator implements MathGenerator {
protected String currentDifficulty;
protected String currentUser;
/**
*
*/
protected boolean validateQuestionCount(int count) {
return count >= 10 && count <= 30 || count == -1;
}
/**
*
*/
protected boolean validateDifficulty(String difficulty) {
return difficulty.equals("小学") || difficulty.equals("初中") || difficulty.equals("高中");
}
/**
*
*/
public String getCurrentDifficulty() {
return currentDifficulty;
}
/**
*
*/
public String getCurrentUser() {
return currentUser;
}
}

@ -0,0 +1,86 @@
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
*
*/
public class FileService {
private final String baseDir;
public FileService() {
this.baseDir = System.getProperty("user.dir") + File.separator + "papers";
initializeStorage();
}
/**
*
*/
private void initializeStorage() {
File dir = new File(baseDir);
if (!dir.exists()) {
dir.mkdirs();
}
}
/**
*
*/
public void saveQuestions(String username, List<String> questions) {
String timestamp = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
String filename = timestamp + ".txt";
String userDirPath = baseDir + File.separator + username;
File userDir = new File(userDirPath);
if (!userDir.exists()) {
userDir.mkdirs();
}
File file = new File(userDir, filename);
try (PrintWriter writer = new PrintWriter(new FileWriter(file, true))) {
for (int i = 0; i < questions.size(); i++) {
writer.println((i + 1) + ". " + questions.get(i));
if (i < questions.size() - 1) {
writer.println();
}
}
} catch (IOException e) {
System.err.println("保存文件失败: " + e.getMessage());
}
}
/**
*
*/
public void loadHistoryQuestions(String username, java.util.Set<String> questionSet) {
File userDir = new File(baseDir + File.separator + username);
if (!userDir.exists() || !userDir.isDirectory()) {
return;
}
File[] files = userDir.listFiles((dir, name) -> name.endsWith(".txt"));
if (files == null) return;
for (File file : files) {
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.matches("^\\d+\\.\\s+.+")) {
String question = line.substring(line.indexOf(".") + 1).trim();
questionSet.add(normalizeQuestion(question));
}
}
} catch (IOException e) {
System.err.println("读取历史题目失败: " + e.getMessage());
}
}
}
/**
*
*/
private String normalizeQuestion(String question) {
return question.replaceAll("\\s+", "").toLowerCase();
}
}

@ -0,0 +1,26 @@
import java.util.List;
/**
*
*/
public interface MathGenerator {
/**
*
*/
List<String> generateQuestions(int count);
/**
*
*/
void switchDifficulty(String level);
/**
*
*/
boolean login(String username, String password);
/**
*
*/
void saveToFile(List<String> questions);
}

@ -1,107 +1,93 @@
import java.io.*;
import java.text.SimpleDateFormat;
import entities.User;
import entities.UserType;
import java.util.*;
/**
*
* -
*
* 1
*/
public class MathTestGenerator {
private static final Map<String, User> USERS = new HashMap<>();
static {
// 小学账户
USERS.put("张三1", new User("张三1", "123", UserType.PRIMARY));
USERS.put("张三2", new User("张三2", "123", UserType.PRIMARY));
USERS.put("张三3", new User("张三3", "123", UserType.PRIMARY));
// 初中账户
USERS.put("李四1", new User("李四1", "123", UserType.JUNIOR));
USERS.put("李四2", new User("李四2", "123", UserType.JUNIOR));
USERS.put("李四3", new User("李四3", "123", UserType.JUNIOR));
// 高中账户
USERS.put("王五1", new User("王五1", "123", UserType.SENIOR));
USERS.put("王五2", new User("王五2", "123", UserType.SENIOR));
USERS.put("王五3", new User("王五3", "123", UserType.SENIOR));
}
public class MathTestGenerator extends AbstractMathGenerator {
private final UserService userService;
private final QuestionService questionService;
private final FileService fileService;
private final ValidationService validationService;
private final Scanner scanner;
// 用户类型枚举
private enum UserType {
PRIMARY("小学"), JUNIOR("初中"), SENIOR("高中");
private User currentUser;
private final String name;
UserType(String name) { this.name = name; }
public String getName() { return name; }
public MathTestGenerator() {
this.userService = new UserService();
this.questionService = new QuestionService();
this.fileService = new FileService();
this.validationService = new ValidationService();
this.scanner = new Scanner(System.in);
}
// 用户类
private static class User {
String username;
String password;
UserType type;
@Override
public boolean login(String username, String password) {
User user = userService.authenticate(username, password);
if (user != null) {
this.currentUser = user;
this.currentDifficulty = user.getType().getName();
System.out.println("当前选择为" + currentDifficulty + "出题");
User(String username, String password, UserType type) {
this.username = username;
this.password = password;
this.type = type;
// 加载历史题目用于查重
Set<String> historyQuestions = new HashSet<>();
fileService.loadHistoryQuestions(username, historyQuestions);
// 这里需要将历史题目传递给questionService
return true;
}
return false;
}
// 运算符枚举
private enum Operator {
ADD("+", 1), SUBTRACT("-", 1), MULTIPLY("*", 2), DIVIDE("/", 2),
POWER("^", 3), SQRT("√", 3), SIN("sin", 4), COS("cos", 4), TAN("tan", 4);
@Override
public List<String> generateQuestions(int count) {
if (currentUser == null) {
throw new IllegalStateException("请先登录");
}
questionService.setCurrentType(UserType.fromName(currentDifficulty));
List<String> questions = new ArrayList<>();
private final String symbol;
private final int priority;
Operator(String symbol, int priority) {
this.symbol = symbol;
this.priority = priority;
for (int i = 0; i < count; i++) {
questions.add(questionService.generateQuestion());
}
public String getSymbol() { return symbol; }
public int getPriority() { return priority; }
return questions;
}
private User currentUser;
private UserType currentType;
private Set<String> generatedQuestions;
private Scanner scanner;
private String baseDir;
@Override
public void switchDifficulty(String level) {
public MathTestGenerator() {
this.scanner = new Scanner(System.in);
this.generatedQuestions = new HashSet<>();
this.baseDir = System.getProperty("user.dir") + File.separator + "papers";
initializeStorage();
this.currentDifficulty = level;
System.out.println("准备生成" + level + "数学题目,请输入生成题目数量");
}
/**
*
*/
private void initializeStorage() {
File dir = new File(baseDir);
if (!dir.exists()) {
dir.mkdirs();
}
@Override
public void saveToFile(List<String> questions) {
fileService.saveQuestions(currentUser.getUsername(), questions);
}
/**
*
*
*/
public void start() {
System.out.println("=== 中小学数学卷子自动生成程序 ===");
while (true) {
if (login()) {
if (performLogin()) {
generatePapers();
}
}
}
/**
*
*
*/
private boolean login() {
private boolean performLogin() {
while (true) {
System.out.print("请输入用户名和密码用空格隔开输入exit退出程序");
String input = scanner.nextLine().trim();
@ -110,21 +96,16 @@ public class MathTestGenerator {
System.exit(0);
}
String[] credentials = input.split("\\s+");
if (credentials.length != 2) {
if (!validationService.isValidCredentialsFormat(input)) {
System.out.println("请输入正确的用户名、密码");
continue;
}
String[] credentials = input.split("\\s+");
String username = credentials[0];
String password = credentials[1];
User user = USERS.get(username);
if (user != null && user.password.equals(password)) {
currentUser = user;
currentType = user.type;
System.out.println("当前选择为" + currentType.getName() + "出题");
loadGeneratedQuestions();
if (login(username, password)) {
return true;
} else {
System.out.println("请输入正确的用户名、密码");
@ -133,261 +114,67 @@ public class MathTestGenerator {
}
/**
*
*/
private void loadGeneratedQuestions() {
generatedQuestions.clear();
File userDir = new File(baseDir + File.separator + currentUser.username);
if (userDir.exists() && userDir.isDirectory()) {
File[] files = userDir.listFiles((dir, name) -> name.endsWith(".txt"));
if (files != null) {
for (File file : files) {
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
if (line.matches("^\\d+\\.\\s+.+")) {
String question = line.substring(line.indexOf(".") + 1).trim();
generatedQuestions.add(normalizeQuestion(question));
}
}
} catch (IOException e) {
System.out.println("读取历史题目失败: " + e.getMessage());
}
}
}
}
}
/**
*
*
*/
private void generatePapers() {
while (true) {
System.out.print("准备生成" + currentType.getName() +
System.out.print("准备生成" + currentDifficulty +
"数学题目请输入生成题目数量10-30输入-1退出当前用户");
String input = scanner.nextLine().trim();
if (input.equals("-1")) {
currentUser = null;
currentType = null;
currentDifficulty = null;
questionService.clearGeneratedQuestions();
System.out.println("已退出当前用户,请重新登录");
return;
}
if (isSwitchCommand(input)) {
if (validationService.isValidSwitchCommand(input)) {
handleSwitchCommand(input);
continue;
}
if (!validationService.isValidQuestionCount(input)) {
System.out.println("题目数量应在10-30之间");
continue;
}
try {
int count = Integer.parseInt(input);
if (count >= 10 && count <= 30) {
generateTestPaper(count);
} else {
System.out.println("题目数量应在10-30之间");
}
} catch (NumberFormatException e) {
System.out.println("请输入有效的数字");
List<String> questions = generateQuestions(count);
saveToFile(questions);
System.out.println("试卷生成成功!生成题目数量:" + questions.size());
} catch (Exception e) {
System.out.println("生成题目失败: " + e.getMessage());
}
}
}
/**
*
*/
private boolean isSwitchCommand(String input) {
return input.startsWith("切换为");
}
/**
*
*/
private void handleSwitchCommand(String input) {
String typeStr = input.substring(3).trim();
try {
UserType newType = UserType.valueOf(typeStr.toUpperCase());
currentType = newType;
System.out.println("准备生成" + currentType.getName() + "数学题目,请输入生成题目数量");
} catch (IllegalArgumentException e) {
System.out.println("请输入小学、初中和高中三个选项中的一个");
}
}
String level = validationService.extractDifficulty(input);
while(!level.equals("小学")&&!level.equals("初中")&&!level.equals("高中")) {
System.out.print("请输入小学、初中和高中三个选项中的一个\n");
Scanner sc = new Scanner(System.in);
/**
*
*/
private void generateTestPaper(int questionCount) {
List<String> questions = new ArrayList<>();
int generated = 0;
int attempts = 0;
final int MAX_ATTEMPTS = 1000;
while (generated < questionCount && attempts < MAX_ATTEMPTS) {
String question = generateQuestion();
String normalized = normalizeQuestion(question);
if (!generatedQuestions.contains(normalized)) {
questions.add(question);
generatedQuestions.add(normalized);
generated++;
}
attempts++;
}
level = validationService.extractDifficulty(sc.nextLine().trim());
if (generated < questionCount) {
System.out.println("警告:无法生成足够的不重复题目,已生成 " + generated + " 道题");
}
saveToFile(questions);
System.out.println("试卷生成成功!");
}
/**
*
*/
private String generateQuestion() {
Random random = new Random();
int operandCount = random.nextInt(5) + 1; // 1-5个操作数
StringBuilder question = new StringBuilder();
List<Integer> operands = new ArrayList<>();
List<Operator> operators = new ArrayList<>();
// 生成操作数
for (int i = 0; i < operandCount; i++) {
operands.add(random.nextInt(100) + 1);
}
// 根据难度生成运算符
switch (currentType) {
case PRIMARY:
generatePrimaryOperators(operators, operandCount - 1, random);
break;
case JUNIOR:
generateJuniorOperators(operators, operandCount - 1, random);
break;
case SENIOR:
generateSeniorOperators(operators, operandCount - 1, random);
break;
}
// 构建题目表达式
question.append(operands.get(0));
for (int i = 0; i < operators.size(); i++) {
Operator op = operators.get(i);
if (op == Operator.SQRT) {
question.insert(0, "√(").append(")");
question.append(op.getSymbol()).append(operands.get(i + 1));
} else if (op == Operator.SIN || op == Operator.COS || op == Operator.TAN) {
question.append(op.getSymbol()).append("(").append(operands.get(i + 1)).append(")");
} else {
question.append(" ").append(op.getSymbol()).append(" ").append(operands.get(i + 1));
}
}
// 随机添加括号
if (operandCount > 2 && random.nextBoolean()) {
question.insert(0, "(");
int insertPos = question.indexOf(" ", question.indexOf(" ") + 1);
if (insertPos != -1) {
question.insert(insertPos + 1, ")");
}
}
return question.toString();
}
/**
*
*/
private void generatePrimaryOperators(List<Operator> operators, int count, Random random) {
Operator[] primaryOps = {Operator.ADD, Operator.SUBTRACT, Operator.MULTIPLY, Operator.DIVIDE};
for (int i = 0; i < count; i++) {
operators.add(primaryOps[random.nextInt(primaryOps.length)]);
}
}
/**
*
*/
private void generateJuniorOperators(List<Operator> operators, int count, Random random) {
Operator[] juniorOps = {Operator.ADD, Operator.SUBTRACT, Operator.MULTIPLY, Operator.DIVIDE,
Operator.POWER, Operator.SQRT};
// 确保至少有一个平方或开根号
boolean hasSpecialOp = false;
for (int i = 0; i < count; i++) {
Operator op = juniorOps[random.nextInt(juniorOps.length)];
if (op == Operator.POWER || op == Operator.SQRT) {
hasSpecialOp = true;
}
operators.add(op);
}
if (!hasSpecialOp && count > 0) {
operators.set(random.nextInt(count),
random.nextBoolean() ? Operator.POWER : Operator.SQRT);
}
}
/**
*
*/
private void generateSeniorOperators(List<Operator> operators, int count, Random random) {
Operator[] seniorOps = {Operator.ADD, Operator.SUBTRACT, Operator.MULTIPLY, Operator.DIVIDE,
Operator.POWER, Operator.SQRT, Operator.SIN, Operator.COS, Operator.TAN};
// 确保至少有一个三角函数
boolean hasTrigOp = false;
for (int i = 0; i < count; i++) {
Operator op = seniorOps[random.nextInt(seniorOps.length)];
if (op == Operator.SIN || op == Operator.COS || op == Operator.TAN) {
hasTrigOp = true;
try {
switchDifficulty(level);
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
operators.add(op);
}
if (!hasTrigOp && count > 0) {
Operator[] trigOps = {Operator.SIN, Operator.COS, Operator.TAN};
operators.set(random.nextInt(count), trigOps[random.nextInt(trigOps.length)]);
}
}
/**
*
*/
private String normalizeQuestion(String question) {
return question.replaceAll("\\s+", "").toLowerCase();
}
/**
*
*/
private void saveToFile(List<String> questions) {
String timestamp = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date());
String filename = timestamp + ".txt";
String userDirPath = baseDir + File.separator + currentUser.username;
File userDir = new File(userDirPath);
if (!userDir.exists()) {
userDir.mkdirs();
}
File file = new File(userDir, filename);
try (PrintWriter writer = new PrintWriter(new FileWriter(file))) {
for (int i = 0; i < questions.size(); i++) {
writer.println((i + 1) + ". " + questions.get(i));
if (i < questions.size() - 1) {
writer.println();
}
}
} catch (IOException e) {
System.out.println("保存文件失败: " + e.getMessage());
}
}
/**
*
*/

@ -0,0 +1,32 @@
package entities;
/**
*
*/
public enum Operator {
ADD("+", 1, "小学初中高中"),
SUBTRACT("-", 1, "小学初中高中"),
MULTIPLY("*", 2, "小学初中高中"),
DIVIDE("/", 2, "小学初中高中"),
POWER("^", 3, "初中高中"),
SQRT("√", 3, "初中高中"),
SIN("sin", 4, "高中"),
COS("cos", 4, "高中"),
TAN("tan", 4, "高中");
private final String symbol;
private final int priority;
private final String allowedLevels;
Operator(String symbol, int priority, String allowedLevels) {
this.symbol = symbol;
this.priority = priority;
this.allowedLevels = allowedLevels;
}
public String getSymbol() { return symbol; }
public int getPriority() { return priority; }
public boolean isAllowedForLevel(String level) {
return allowedLevels.contains(level);
}
}

@ -0,0 +1,192 @@
import entities.Operator;
import entities.UserType;
import java.util.*;
/**
*
*/
public class QuestionService {
private final Random random;
private final Set<String> generatedQuestions;
private UserType currentType;
public QuestionService() {
this.random = new Random();
this.generatedQuestions = new HashSet<>();
}
/**
*
*/
public void setCurrentType(UserType type) {
this.currentType = type;
}
/**
*
*/
public String generateQuestion() {
String question;
int attempts = 0;
do {
question = generateUniqueQuestion();
attempts++;
} while (generatedQuestions.contains(normalizeQuestion(question)) && attempts < 100);
generatedQuestions.add(normalizeQuestion(question));
return question;
}
/**
*
*/
private String generateUniqueQuestion() {
int operandCount = random.nextInt(5) + 1;
List<Integer> operands = generateOperands(operandCount);
List<Operator> operators = generateOperators(operandCount - 1);
return buildExpression(operands, operators);
}
/**
*
*/
private List<Integer> generateOperands(int count) {
List<Integer> operands = new ArrayList<>();
for (int i = 0; i < count; i++) {
operands.add(random.nextInt(100) + 1);
}
return operands;
}
/**
*
*/
private List<Operator> generateOperators(int count) {
List<Operator> operators = new ArrayList<>();
List<Operator> allowedOperators = getAllowedOperators();
// 确保符合难度要求
if (currentType == UserType.JUNIOR) {
ensureJuniorRequirement(operators, allowedOperators, count);
} else if (currentType == UserType.SENIOR) {
ensureSeniorRequirement(operators, allowedOperators, count);
} else {
for (int i = 0; i < count; i++) {
operators.add(allowedOperators.get(random.nextInt(allowedOperators.size())));
}
}
return operators;
}
/**
*
*/
private List<Operator> getAllowedOperators() {
List<Operator> allowed = new ArrayList<>();
String level = currentType.getName();
for (Operator op : Operator.values()) {
if (op.isAllowedForLevel(level)) {
allowed.add(op);
}
}
return allowed;
}
/**
*
*/
private void ensureJuniorRequirement(List<Operator> operators, List<Operator> allowed, int count) {
boolean hasSpecialOp = false;
for (int i = 0; i < count; i++) {
Operator op = allowed.get(random.nextInt(allowed.size()));
operators.add(op);
if (op == Operator.POWER || op == Operator.SQRT) {
hasSpecialOp = true;
}
}
if (!hasSpecialOp && count > 0) {
int index = random.nextInt(operators.size());
operators.set(index, random.nextBoolean() ? Operator.POWER : Operator.SQRT);
}
}
/**
*
*/
private void ensureSeniorRequirement(List<Operator> operators, List<Operator> allowed, int count) {
boolean hasTrigOp = false;
for (int i = 0; i < count; i++) {
Operator op = allowed.get(random.nextInt(allowed.size()));
operators.add(op);
if (op == Operator.SIN || op == Operator.COS || op == Operator.TAN) {
hasTrigOp = true;
}
}
if (!hasTrigOp && count > 0) {
int index = random.nextInt(operators.size());
Operator[] trigOps = {Operator.SIN, Operator.COS, Operator.TAN};
operators.set(index, trigOps[random.nextInt(trigOps.length)]);
}
}
/**
*
*/
private String buildExpression(List<Integer> operands, List<Operator> operators) {
StringBuilder expression = new StringBuilder();
expression.append(operands.get(0));
for (int i = 0; i < operators.size(); i++) {
Operator op = operators.get(i);
int operand = operands.get(i + 1);
switch (op) {
case SQRT:
expression.insert(0, "√(").append(")");
expression.append(op.getSymbol()).append(operand);
break;
case SIN:
case COS:
case TAN:
expression.append(op.getSymbol()).append("(").append(operand).append(")");
break;
default:
expression.append(" ").append(op.getSymbol()).append(" ").append(operand);
}
}
// 随机添加括号
if (operands.size() > 2 && random.nextBoolean()) {
expression.insert(0, "(");
int spaceIndex = expression.indexOf(" ", expression.indexOf(" ") + 1);
if (spaceIndex != -1) {
expression.insert(spaceIndex + 1, ")");
}
}
return expression.toString();
}
/**
*
*/
private String normalizeQuestion(String question) {
return question.replaceAll("\\s+", "").toLowerCase();
}
/**
* 退
*/
public void clearGeneratedQuestions() {
generatedQuestions.clear();
}
}

@ -0,0 +1,21 @@
package entities;
/**
*
*/
public class User {
private String username;
private String password;
private UserType type;
public User(String username, String password, UserType type) {
this.username = username;
this.password = password;
this.type = type;
}
// Getter方法
public String getUsername() { return username; }
public String getPassword() { return password; }
public UserType getType() { return type; }
}

@ -0,0 +1,54 @@
import entities.User;
import entities.UserType;
import java.util.HashMap;
import java.util.Map;
/**
*
*/
public class UserService {
private final Map<String, User> users;
public UserService() {
this.users = new HashMap<>();
initializeUsers();
}
/**
*
*/
private void initializeUsers() {
// 小学账户
users.put("张三1", new User("张三1", "123", UserType.PRIMARY));
users.put("张三2", new User("张三2", "123", UserType.PRIMARY));
users.put("张三3", new User("张三3", "123", UserType.PRIMARY));
// 初中账户
users.put("李四1", new User("李四1", "123", UserType.JUNIOR));
users.put("李四2", new User("李四2", "123", UserType.JUNIOR));
users.put("李四3", new User("李四3", "123", UserType.JUNIOR));
// 高中账户
users.put("王五1", new User("王五1", "123", UserType.SENIOR));
users.put("王五2", new User("王五2", "123", UserType.SENIOR));
users.put("王五3", new User("王五3", "123", UserType.SENIOR));
}
/**
*
*/
public User authenticate(String username, String password) {
User user = users.get(username);
if (user != null && user.getPassword().equals(password)) {
return user;
}
return null;
}
/**
*
*/
public Map<String, User> getUsers() {
return new HashMap<>(users);
}
}

@ -0,0 +1,32 @@
package entities;
/**
*
*/
public enum UserType {
PRIMARY("小学"),
JUNIOR("初中"),
SENIOR("高中");
private final String name;
UserType(String name) {
this.name = name;
}
public String getName() {
return name;
}
/**
*
*/
public static UserType fromName(String name) {
for (UserType type : values()) {
if (type.name.equals(name)) {
return type;
}
}
throw new IllegalArgumentException("无效的用户类型: " + name);
}
}

@ -0,0 +1,49 @@
import java.util.regex.Pattern;
/**
*
*/
public class ValidationService {
/**
*
*/
public boolean isValidSwitchCommand(String input) {
if (!input.startsWith("切换为")) {
return false;
}
return true;
}
/**
*
*/
public boolean isValidQuestionCount(String input) {
if (input.equals("-1")) {
return true;
}
try {
int count = Integer.parseInt(input);
return count >= 10 && count <= 30;
} catch (NumberFormatException e) {
return false;
}
}
/**
*
*/
public boolean isValidCredentialsFormat(String input) {
String[] parts = input.split("\\s+");
return parts.length == 2;
}
/**
*
*/
public String extractDifficulty(String switchCommand) {
return switchCommand.substring(3).trim();
}
}
Loading…
Cancel
Save