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