main
parent
d69ef66f3b
commit
e1dd7a5988
@ -0,0 +1,29 @@
|
||||
# 中小学数学卷子自动生成程序
|
||||
|
||||
## 项目简介
|
||||
本项目是一个面向中小学数学老师的卷子自动生成程序。
|
||||
|
||||
## 功能特性
|
||||
- ✅ **用户登录**:支持预设账号登录验证
|
||||
- ✅ **题目生成**:自动生成符合难度的数学题目
|
||||
- ✅ **难度切换**:支持小学、初中、高中难度切换
|
||||
- ✅ **题目查重**:避免生成重复题目
|
||||
|
||||
## 注意事项
|
||||
- 使用切换功能时无提示,在“准备生成 XX 数学题目,请输入生成题目数量(输入-1
|
||||
将退出当前用户,重新登录):”的阶段切换
|
||||
|
||||
- 提示请输入小学、初中和高中三个选项中的一个后仍输入“切换为XX”
|
||||
正确更改后才可退出
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 环境要求
|
||||
- Java 8+
|
||||
- 至少 100MB 磁盘空间
|
||||
|
||||
### 安装运行
|
||||
```bash
|
||||
cd src
|
||||
javac -encoding UTF-8 *.java
|
||||
java MathTestGenerator
|
@ -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);
|
||||
}
|
@ -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,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,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…
Reference in new issue