You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Rumia/src/MathQuestionGenerator.java

454 lines
15 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;
/**
* 中小学数学卷子自动生成程序
* 支持小学、初中、高中三个学段的数学题目生成
*/
public class MathQuestionGenerator {
// 常量定义
private static final int MIN_OPERAND_COUNT = 1;
private static final int MAX_OPERAND_COUNT = 5;
private static final int MIN_OPERAND_VALUE = 1;
private static final int MAX_OPERAND_VALUE = 100;
private static final int MIN_QUESTION_COUNT = 10;
private static final int MAX_QUESTION_COUNT = 30;
private static final int MAX_GENERATION_ATTEMPTS = 100;
// 预定义的用户账户
private static final Map<String, User> USERS = new HashMap<>();
// 题目生成器映射
private static final Map<String, QuestionGenerator> GENERATORS = new HashMap<>();
// 当前登录用户
private static User currentUser = null;
private static final Scanner scanner = new Scanner(System.in);
static {
initializeUsers();
initializeGenerators();
}
/**
* 初始化用户账户
*/
private static void initializeUsers() {
// 小学老师
USERS.put("张三1", new User("张三1", "123", "小学"));
USERS.put("张三2", new User("张三2", "123", "小学"));
USERS.put("张三3", new User("张三3", "123", "小学"));
// 初中老师
USERS.put("李四1", new User("李四1", "123", "初中"));
USERS.put("李四2", new User("李四2", "123", "初中"));
USERS.put("李四3", new User("李四3", "123", "初中"));
// 高中老师
USERS.put("王五1", new User("王五1", "123", "高中"));
USERS.put("王五2", new User("王五2", "123", "高中"));
USERS.put("王五3", new User("王五3", "123", "高中"));
}
/**
* 初始化题目生成器
*/
private static void initializeGenerators() {
GENERATORS.put("小学", new PrimaryQuestionGenerator());
GENERATORS.put("初中", new JuniorQuestionGenerator());
GENERATORS.put("高中", new SeniorQuestionGenerator());
}
/**
* 主程序入口
* @param args 命令行参数
*/
public static void main(String[] args) {
showWelcomeMessage();
while (true) {
if (!login()) {
continue;
}
System.out.println("登录成功!欢迎 " + currentUser.getUsername() + " 老师");
operateAfterLogin();
}
}
/**
* 显示欢迎信息
*/
private static void showWelcomeMessage() {
System.out.println("==========================================");
System.out.println(" 中小学数学卷子自动生成系统 ");
System.out.println("==========================================");
System.out.println();
System.out.println("预设账户信息:");
System.out.println("小学老师张三1、张三2、张三3密码123");
System.out.println("初中老师李四1、李四2、李四3密码123");
System.out.println("高中老师王五1、王五2、王五3密码123");
System.out.println();
}
/**
* 用户登录验证
* @return 登录是否成功
*/
private static boolean login() {
System.out.println("=== 用户登录 ===");
System.out.println("请输入用户名和密码(用空格隔开):");
System.out.print("> ");
String input = scanner.nextLine().trim();
String[] parts = input.split("\\s+");
if (parts.length != 2) {
System.out.println("请输入正确的用户名、密码");
return false;
}
String username = parts[0];
String password = parts[1];
User user = USERS.get(username);
if (user != null && user.getPassword().equals(password)) {
currentUser = user;
return true;
} else {
System.out.println("请输入正确的用户名、密码");
return false;
}
}
/**
* 登录后的操作处理
*/
private static void operateAfterLogin() {
String currentGrade = currentUser.getGrade();
showOperationMenu(currentGrade);
while (true) {
String input = getUserInput();
if (handleExitCommand(input)) {
break;
}
if (input.startsWith("切换为")) {
if (handleSwitchCommand(input)) {
currentGrade = currentUser.getGrade();
showOperationMenu(currentGrade);
}
continue;
}
handleQuestionGeneration(input, currentGrade);
}
}
/**
* 获取用户输入
* @return 用户输入
*/
private static String getUserInput() {
System.out.println();
System.out.print("请输入操作:");
return scanner.nextLine().trim();
}
/**
* 处理退出命令
* @param input 用户输入
* @return 是否退出
*/
private static boolean handleExitCommand(String input) {
if (input.equals("-1")) {
currentUser = null;
System.out.println("退出当前用户,重新登录...");
return true;
}
return false;
}
/**
* 处理题目生成
* @param input 用户输入
* @param currentGrade 当前年级
*/
private static void handleQuestionGeneration(String input, String currentGrade) {
try {
int count = Integer.parseInt(input);
if (count < MIN_QUESTION_COUNT || count > MAX_QUESTION_COUNT) {
System.out.println("题目数量应在" + MIN_QUESTION_COUNT + "-" + MAX_QUESTION_COUNT + "之间");
return;
}
generateQuestions(count, currentGrade);
} catch (NumberFormatException e) {
System.out.println("请输入有效的数字(" + MIN_QUESTION_COUNT + "-" + MAX_QUESTION_COUNT + ")或切换命令");
}
}
/**
* 显示操作菜单
* @param currentGrade 当前年级类型
*/
private static void showOperationMenu(String currentGrade) {
System.out.println();
System.out.println("=== 操作菜单 ===");
System.out.println("当前选择为" + currentGrade + "出题");
System.out.println();
System.out.println("可进行的操作:");
System.out.println("1. 输入数字 " + MIN_QUESTION_COUNT + "-" + MAX_QUESTION_COUNT + ":生成指定数量的" + currentGrade + "数学题目");
System.out.println("2. 输入 '切换为小学':切换到小学出题模式");
System.out.println("3. 输入 '切换为初中':切换到初中出题模式");
System.out.println("4. 输入 '切换为高中':切换到高中出题模式");
System.out.println("5. 输入 '-1':退出当前用户,重新登录");
System.out.println();
System.out.flush();
}
/**
* 处理切换命令
* @param command 切换命令
* @return 切换是否成功
*/
private static boolean handleSwitchCommand(String command) {
String targetGrade = command.substring(3).trim();
if (targetGrade.equals("小学") || targetGrade.equals("初中") || targetGrade.equals("高中")) {
currentUser = new User(currentUser.getUsername(), currentUser.getPassword(), targetGrade);
System.out.println();
System.out.println("✓ 切换成功!当前为" + targetGrade + "出题模式");
System.out.flush();
return true;
} else {
System.out.println();
System.out.println("✗ 请输入小学、初中和高中三个选项中的一个");
System.out.flush();
return false;
}
}
/**
* 生成指定数量的题目
* @param count 题目数量
* @param grade 年级类型
*/
private static void generateQuestions(int count, String grade) {
File userDir = createUserDirectory();
Set<String> historyQuestions = loadHistoryQuestions(userDir);
List<String> newQuestions = generateNewQuestions(count, grade, historyQuestions);
saveQuestionsToFile(newQuestions, userDir, count, grade);
}
/**
* 创建用户文件夹
* @return 用户文件夹
*/
private static File createUserDirectory() {
File userDir = new File(currentUser.getUsername());
if (!userDir.exists()) {
userDir.mkdir();
}
return userDir;
}
/**
* 生成新题目
* @param count 题目数量
* @param grade 年级类型
* @param historyQuestions 历史题目
* @return 新题目列表
*/
private static List<String> generateNewQuestions(int count, String grade, Set<String> historyQuestions) {
List<String> newQuestions = new ArrayList<>();
Random random = new Random();
QuestionGenerator generator = GENERATORS.get(grade);
for (int i = 1; i <= count; i++) {
String question = generateSingleQuestion(generator, random, historyQuestions, newQuestions, i);
newQuestions.add(question);
}
return newQuestions;
}
/**
* 生成单个题目
* @param generator 题目生成器
* @param random 随机数生成器
* @param historyQuestions 历史题目
* @param newQuestions 新题目列表
* @param questionNumber 题目编号
* @return 生成的题目
*/
private static String generateSingleQuestion(QuestionGenerator generator, Random random,
Set<String> historyQuestions, List<String> newQuestions,
int questionNumber) {
String question;
int attempts = 0;
do {
int operandCount = random.nextInt(MAX_OPERAND_COUNT - MIN_OPERAND_COUNT + 1) + MIN_OPERAND_COUNT;
int[] operands = new int[operandCount];
for (int i = 0; i < operandCount; i++) {
operands[i] = random.nextInt(MAX_OPERAND_VALUE - MIN_OPERAND_VALUE + 1) + MIN_OPERAND_VALUE;
}
question = generator.generateQuestion(operands, random);
attempts++;
if (attempts > MAX_GENERATION_ATTEMPTS) {
question = "备用题目:" + questionNumber;
break;
}
} while (historyQuestions.contains(question) || newQuestions.contains(question));
return question;
}
/**
* 加载历史题目用于去重
* @param userDir 用户文件夹
* @return 历史题目集合
*/
private static Set<String> loadHistoryQuestions(File userDir) {
Set<String> historyQuestions = new HashSet<>();
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();
historyQuestions.add(question);
}
}
} catch (IOException e) {
System.out.println("读取历史文件失败:" + file.getName());
}
}
}
return historyQuestions;
}
/**
* 保存题目到文件
* @param questions 题目列表
* @param userDir 用户文件夹
* @param count 题目数量
* @param grade 年级类型
*/
private static void saveQuestionsToFile(List<String> questions, File userDir, int count, String grade) {
File outputFile = createOutputFile(userDir);
writeQuestionsToFile(questions, outputFile);
showGenerationResult(count, grade, outputFile);
}
/**
* 创建输出文件
* @param userDir 用户文件夹
* @return 输出文件
*/
private static File createOutputFile(File userDir) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
String filename = dateFormat.format(new Date()) + ".txt";
return new File(userDir, filename);
}
/**
* 将题目写入文件
* @param questions 题目列表
* @param outputFile 输出文件
*/
private static void writeQuestionsToFile(List<String> questions, File outputFile) {
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
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());
}
}
/**
* 显示生成结果
* @param count 题目数量
* @param grade 年级类型
* @param outputFile 输出文件
*/
private static void showGenerationResult(int count, String grade, File outputFile) {
System.out.println();
System.out.println("✓ 题目生成完成!");
System.out.println("✓ 已生成 " + count + " 道" + grade + "数学题目");
System.out.println("✓ 文件已保存到:" + outputFile.getName());
System.out.println();
}
/**
* 用户类,存储用户信息
*/
static class User {
private final String username;
private final String password;
private final String grade;
/**
* 构造函数
* @param username 用户名
* @param password 密码
* @param grade 年级类型
*/
public User(String username, String password, String grade) {
this.username = username;
this.password = password;
this.grade = grade;
}
/**
* 获取用户名
* @return 用户名
*/
public String getUsername() {
return username;
}
/**
* 获取密码
* @return 密码
*/
public String getPassword() {
return password;
}
/**
* 获取年级类型
* @return 年级类型
*/
public String getGrade() {
return grade;
}
}
}