中小学数学卷子自动生成程序zgc #1

Merged
pta2mvbfs merged 3 commits from develop into main 5 months ago

@ -0,0 +1,39 @@
/**
*
*
*/
public class MathQuestion {
private String expression;
private String answer;
public MathQuestion(String expression, String answer) {
this.expression = expression;
this.answer = answer;
}
public String getExpression() {
return expression;
}
public String getAnswer() {
return answer;
}
@Override
public String toString() {
return expression;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
MathQuestion that = (MathQuestion) obj;
return expression.equals(that.expression);
}
@Override
public int hashCode() {
return expression.hashCode();
}
}

@ -0,0 +1,148 @@
import java.util.*;
/**
*
*
*/
public class MathQuestionGenerator {
private Random random;
private String[] operators = {"+", "-", "*", "/"};
private String[] trigFunctions = {"sin", "cos", "tan"};
public MathQuestionGenerator() {
this.random = new Random();
}
/**
*
* @param accountType
* @param count
* @return
*/
public List<MathQuestion> generateQuestions(String accountType, int count) {
List<MathQuestion> questions = new ArrayList<>();
for (int i = 0; i < count; i++) {
MathQuestion question;
switch (accountType) {
case "小学":
question = generateElementaryQuestion();
break;
case "初中":
question = generateMiddleSchoolQuestion();
break;
case "高中":
question = generateHighSchoolQuestion();
break;
default:
question = generateElementaryQuestion();
}
questions.add(question);
}
return questions;
}
/**
* +-*/()
*/
private MathQuestion generateElementaryQuestion() {
int operatorCount = random.nextInt(4) + 1; // 1-4个操作符
List<Integer> numbers = new ArrayList<>();
List<String> ops = new ArrayList<>();
// 生成数字1-100
for (int i = 0; i <= operatorCount; i++) {
numbers.add(random.nextInt(100) + 1);
}
// 生成操作符
for (int i = 0; i < operatorCount; i++) {
ops.add(operators[random.nextInt(operators.length)]);
}
// 构建表达式
StringBuilder expression = new StringBuilder();
expression.append(numbers.get(0));
for (int i = 0; i < operatorCount; i++) {
expression.append(" ").append(ops.get(i)).append(" ").append(numbers.get(i + 1));
}
// 可能添加括号
if (operatorCount >= 2 && random.nextBoolean()) {
expression = addParentheses(expression.toString());
}
return new MathQuestion(expression.toString(), "计算结果");
}
/**
*
*/
private MathQuestion generateMiddleSchoolQuestion() {
StringBuilder expression = new StringBuilder();
// 基础部分
int num1 = random.nextInt(50) + 1;
String op = operators[random.nextInt(operators.length)];
expression.append(num1).append(" ").append(op).append(" ");
// 添加平方或开根号
if (random.nextBoolean()) {
// 添加平方
int baseNum = random.nextInt(20) + 1;
expression.append(baseNum).append("²");
} else {
// 添加开根号
int sqrtNum = getRandomPerfectSquare();
expression.append("√").append(sqrtNum);
}
return new MathQuestion(expression.toString(), "计算结果");
}
/**
* sincostan
*/
private MathQuestion generateHighSchoolQuestion() {
StringBuilder expression = new StringBuilder();
// 基础部分
int num1 = random.nextInt(100) + 1;
String op = operators[random.nextInt(operators.length)];
// 添加三角函数
String trigFunc = trigFunctions[random.nextInt(trigFunctions.length)];
int angle = random.nextInt(360); // 0-359度
expression.append(num1).append(" ").append(op).append(" ").append(trigFunc).append("(").append(angle).append("°)");
return new MathQuestion(expression.toString(), "计算结果");
}
/**
*
*/
private StringBuilder addParentheses(String expression) {
String[] parts = expression.split(" ");
if (parts.length >= 5) { // 至少有3个数字和2个操作符
StringBuilder result = new StringBuilder();
result.append("(").append(parts[0]).append(" ").append(parts[1]).append(" ").append(parts[2]).append(")");
for (int i = 3; i < parts.length; i++) {
result.append(" ").append(parts[i]);
}
return result;
}
return new StringBuilder(expression);
}
/**
*
*/
private int getRandomPerfectSquare() {
int[] perfectSquares = {1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400};
return perfectSquares[random.nextInt(perfectSquares.length)];
}
}

@ -0,0 +1,196 @@
import java.util.*;
/**
* -
*
*/
public class MathTestGenerator {
private UserManager userManager;
private MathQuestionGenerator questionGenerator;
private QuestionManager questionManager;
private Scanner scanner;
private User currentUser;
private String currentAccountType;
public MathTestGenerator() {
this.userManager = new UserManager();
this.questionGenerator = new MathQuestionGenerator();
this.questionManager = new QuestionManager();
this.scanner = new Scanner(System.in);
this.currentUser = null;
this.currentAccountType = null;
}
/**
*
*/
public void run() {
System.out.println("=== 中小学数学卷子自动生成程序 ===");
while (true) {
if (currentUser == null) {
// 未登录状态
if (!login()) {
continue; // 登录失败,重新登录
}
} else {
// 已登录状态
handleLoggedInUser();
}
}
}
/**
*
* @return
*/
private boolean login() {
System.out.print("请输入用户名和密码(用空格隔开):");
System.out.flush(); // 强制刷新输出缓冲区
String input = scanner.nextLine().trim();
if (input.isEmpty()) {
System.out.println("请输入正确的用户名、密码");
return false;
}
String[] credentials = input.split("\\s+");
if (credentials.length != 2) {
System.out.println("请输入正确的用户名、密码");
return false;
}
String username = credentials[0];
String password = credentials[1];
User user = userManager.authenticate(username, password);
if (user != null) {
currentUser = user;
currentAccountType = user.getAccountType();
System.out.println("当前选择为" + currentAccountType + "出题");
return true;
} else {
System.out.println("请输入正确的用户名、密码");
return false;
}
}
/**
*
*/
private void handleLoggedInUser() {
System.out.print("准备生成" + currentAccountType + "数学题目,请输入生成题目数量(输入-1将退出当前用户重新登录");
System.out.flush();
String input = scanner.nextLine().trim();
// 检查是否是切换类型命令
if (input.startsWith("切换为")) {
handleAccountTypeSwitch(input);
return;
}
try {
int count = Integer.parseInt(input);
if (count == -1) {
// 退出当前用户
currentUser = null;
currentAccountType = null;
System.out.println("已退出当前用户");
return;
}
if (count < 10 || count > 30) {
System.out.println("题目数量必须在10-30之间请重新输入");
return;
}
// 生成题目
generateAndSaveQuestions(count);
} catch (NumberFormatException e) {
System.out.println("请输入有效的数字或切换命令");
}
}
/**
*
* @param input
*/
private void handleAccountTypeSwitch(String input) {
String newType = input.substring(3); // 去掉"切换为"
if (!userManager.isValidAccountType(newType)) {
System.out.println("请输入小学、初中和高中三个选项中的一个");
return;
}
currentAccountType = newType;
System.out.print("准备生成" + currentAccountType + "数学题目,请输入生成题目数量:");
System.out.flush();
String countInput = scanner.nextLine().trim();
try {
int count = Integer.parseInt(countInput);
if (count < 10 || count > 30) {
System.out.println("题目数量必须在10-30之间");
return;
}
generateAndSaveQuestions(count);
} catch (NumberFormatException e) {
System.out.println("请输入有效的数字");
}
}
/**
*
* @param count
*/
private void generateAndSaveQuestions(int count) {
System.out.println("正在生成" + count + "道" + currentAccountType + "数学题目...");
// 生成不重复的题目
List<MathQuestion> questions = questionManager.generateUniqueQuestions(
currentAccountType, count, questionGenerator);
if (questions.size() < count) {
System.out.println("注意:由于去重要求,实际生成了" + questions.size() + "道题目");
}
if (questions.isEmpty()) {
System.out.println("无法生成新的题目,可能所有题目都已存在");
return;
}
// 保存到文件
String fileName = questionManager.saveQuestionsToFile(currentAccountType, questions);
if (fileName != null) {
System.out.println("题目已保存到文件:" + currentAccountType + "/" + fileName);
System.out.println("共生成" + questions.size() + "道题目");
// 显示前几道题目作为预览
System.out.println("\n题目预览");
for (int i = 0; i < Math.min(3, questions.size()); i++) {
System.out.println((i + 1) + ". " + questions.get(i).getExpression());
}
if (questions.size() > 3) {
System.out.println("...");
}
} else {
System.out.println("保存文件失败");
}
}
/**
*
*/
public static void main(String[] args) {
MathTestGenerator generator = new MathTestGenerator();
generator.run();
}
}

@ -0,0 +1,162 @@
import java.io.*;
import java.nio.file.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
*
*
*/
public class QuestionManager {
private Map<String, Set<String>> userQuestions; // 存储每个用户的历史题目
public QuestionManager() {
this.userQuestions = new HashMap<>();
loadExistingQuestions();
}
/**
*
*/
private void loadExistingQuestions() {
try {
// 为每个用户类型创建目录
createDirectoryIfNotExists("小学");
createDirectoryIfNotExists("初中");
createDirectoryIfNotExists("高中");
// 扫描已存在的文件并加载题目
scanExistingFiles("小学");
scanExistingFiles("初中");
scanExistingFiles("高中");
} catch (Exception e) {
System.err.println("加载历史题目时出错: " + e.getMessage());
}
}
/**
*
*/
private void createDirectoryIfNotExists(String accountType) throws IOException {
Path path = Paths.get(accountType);
if (!Files.exists(path)) {
Files.createDirectories(path);
}
}
/**
*
*/
private void scanExistingFiles(String accountType) {
try {
Path accountDir = Paths.get(accountType);
if (Files.exists(accountDir)) {
Files.walk(accountDir)
.filter(Files::isRegularFile)
.filter(path -> path.toString().endsWith(".txt"))
.forEach(this::loadQuestionsFromFile);
}
} catch (IOException e) {
System.err.println("扫描文件时出错: " + e.getMessage());
}
}
/**
*
*/
private void loadQuestionsFromFile(Path filePath) {
try {
String accountType = filePath.getParent().getFileName().toString();
Set<String> questions = userQuestions.computeIfAbsent(accountType, k -> new HashSet<>());
List<String> lines = Files.readAllLines(filePath);
for (String line : lines) {
line = line.trim();
if (line.matches("\\d+\\..*")) { // 题号格式1. 题目内容
String question = line.substring(line.indexOf('.') + 1).trim();
questions.add(question);
}
}
} catch (IOException e) {
System.err.println("读取文件时出错: " + e.getMessage());
}
}
/**
*
* @param accountType
* @param newQuestions
* @return
*/
public List<MathQuestion> checkAndRemoveDuplicates(String accountType, List<MathQuestion> newQuestions) {
Set<String> existingQuestions = userQuestions.computeIfAbsent(accountType, k -> new HashSet<>());
List<MathQuestion> uniqueQuestions = new ArrayList<>();
for (MathQuestion question : newQuestions) {
if (!existingQuestions.contains(question.getExpression())) {
uniqueQuestions.add(question);
existingQuestions.add(question.getExpression());
}
}
return uniqueQuestions;
}
/**
*
* @param accountType
* @param questions
* @return
*/
public String saveQuestionsToFile(String accountType, List<MathQuestion> questions) {
try {
// 生成文件名:年-月-日-时-分-秒.txt
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss");
String fileName = now.format(formatter) + ".txt";
// 创建文件路径
Path accountDir = Paths.get(accountType);
Path filePath = accountDir.resolve(fileName);
// 写入文件
try (BufferedWriter writer = Files.newBufferedWriter(filePath)) {
for (int i = 0; i < questions.size(); i++) {
writer.write((i + 1) + ". " + questions.get(i).getExpression());
writer.newLine();
if (i < questions.size() - 1) {
writer.newLine(); // 题目之间空一行
}
}
}
return fileName;
} catch (IOException e) {
System.err.println("保存文件时出错: " + e.getMessage());
return null;
}
}
/**
*
* @param accountType
* @param requestedCount
* @param generator
* @return
*/
public List<MathQuestion> generateUniqueQuestions(String accountType, int requestedCount, MathQuestionGenerator generator) {
List<MathQuestion> allQuestions = new ArrayList<>();
int maxAttempts = requestedCount * 3; // 最多尝试3倍数量
int attempts = 0;
while (allQuestions.size() < requestedCount && attempts < maxAttempts) {
List<MathQuestion> newQuestions = generator.generateQuestions(accountType, requestedCount - allQuestions.size());
List<MathQuestion> uniqueQuestions = checkAndRemoveDuplicates(accountType, newQuestions);
allQuestions.addAll(uniqueQuestions);
attempts++;
}
return allQuestions;
}
}

@ -0,0 +1,200 @@
import java.util.*;
import java.io.*;
/**
*
*
*/
public class SimpleMathTestGenerator {
private UserManager userManager;
private MathQuestionGenerator questionGenerator;
private QuestionManager questionManager;
private BufferedReader reader;
private User currentUser;
private String currentAccountType;
public SimpleMathTestGenerator() {
this.userManager = new UserManager();
this.questionGenerator = new MathQuestionGenerator();
this.questionManager = new QuestionManager();
this.reader = new BufferedReader(new InputStreamReader(System.in));
this.currentUser = null;
this.currentAccountType = null;
}
/**
*
*/
public void run() {
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();
try {
while (true) {
if (currentUser == null) {
if (!login()) {
continue;
}
} else {
handleLoggedInUser();
}
}
} catch (IOException e) {
System.out.println("程序输入输出错误:" + e.getMessage());
}
}
/**
*
*/
private boolean login() throws IOException {
System.out.print("请输入用户名和密码(用空格隔开):");
String input = reader.readLine();
if (input == null || input.trim().isEmpty()) {
System.out.println("请输入正确的用户名、密码");
return false;
}
input = input.trim();
String[] credentials = input.split("\\s+");
if (credentials.length != 2) {
System.out.println("请输入正确的用户名、密码");
return false;
}
String username = credentials[0];
String password = credentials[1];
User user = userManager.authenticate(username, password);
if (user != null) {
currentUser = user;
currentAccountType = user.getAccountType();
System.out.println("当前选择为" + currentAccountType + "出题");
return true;
} else {
System.out.println("请输入正确的用户名、密码");
return false;
}
}
/**
*
*/
private void handleLoggedInUser() throws IOException {
System.out.print("准备生成" + currentAccountType + "数学题目,请输入生成题目数量(输入-1将退出当前用户重新登录");
String input = reader.readLine();
if (input == null) {
return;
}
input = input.trim();
// 检查是否是切换类型命令
if (input.startsWith("切换为")) {
handleAccountTypeSwitch(input);
return;
}
try {
int count = Integer.parseInt(input);
if (count == -1) {
currentUser = null;
currentAccountType = null;
System.out.println("已退出当前用户");
return;
}
if (count < 10 || count > 30) {
System.out.println("题目数量必须在10-30之间请重新输入");
return;
}
generateAndSaveQuestions(count);
} catch (NumberFormatException e) {
System.out.println("请输入有效的数字或切换命令");
}
}
/**
*
*/
private void handleAccountTypeSwitch(String input) throws IOException {
String newType = input.substring(3);
if (!userManager.isValidAccountType(newType)) {
System.out.println("请输入小学、初中和高中三个选项中的一个");
return;
}
currentAccountType = newType;
System.out.print("准备生成" + currentAccountType + "数学题目,请输入生成题目数量:");
String countInput = reader.readLine();
if (countInput == null) {
return;
}
try {
int count = Integer.parseInt(countInput.trim());
if (count < 10 || count > 30) {
System.out.println("题目数量必须在10-30之间");
return;
}
generateAndSaveQuestions(count);
} catch (NumberFormatException e) {
System.out.println("请输入有效的数字");
}
}
/**
*
*/
private void generateAndSaveQuestions(int count) {
System.out.println("正在生成" + count + "道" + currentAccountType + "数学题目...");
List<MathQuestion> questions = questionManager.generateUniqueQuestions(
currentAccountType, count, questionGenerator);
if (questions.size() < count) {
System.out.println("注意:由于去重要求,实际生成了" + questions.size() + "道题目");
}
if (questions.isEmpty()) {
System.out.println("无法生成新的题目,可能所有题目都已存在");
return;
}
String fileName = questionManager.saveQuestionsToFile(currentAccountType, questions);
if (fileName != null) {
System.out.println("题目已保存到文件:" + currentAccountType + "/" + fileName);
System.out.println("共生成" + questions.size() + "道题目");
System.out.println("\n题目预览");
for (int i = 0; i < Math.min(3, questions.size()); i++) {
System.out.println((i + 1) + ". " + questions.get(i).getExpression());
}
if (questions.size() > 3) {
System.out.println("...");
}
System.out.println();
} else {
System.out.println("保存文件失败");
}
}
public static void main(String[] args) {
SimpleMathTestGenerator generator = new SimpleMathTestGenerator();
generator.run();
}
}

@ -0,0 +1,35 @@
/**
*
*
*/
public class User {
private String username;
private String password;
private String accountType; // 小学、初中、高中
public User(String username, String password, String accountType) {
this.username = username;
this.password = password;
this.accountType = accountType;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getAccountType() {
return accountType;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", accountType='" + accountType + '\'' +
'}';
}
}

@ -0,0 +1,59 @@
import java.util.HashMap;
import java.util.Map;
/**
*
*
*/
public class UserManager {
private Map<String, User> users;
public UserManager() {
users = new HashMap<>();
initializeUsers();
}
/**
*
* 13
*/
private 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", "高中"));
}
/**
*
* @param username
* @param password
* @return Usernull
*/
public User authenticate(String username, String password) {
User user = users.get(username);
if (user != null && user.getPassword().equals(password)) {
return user;
}
return null;
}
/**
*
* @param accountType
* @return
*/
public boolean isValidAccountType(String accountType) {
return "小学".equals(accountType) || "初中".equals(accountType) || "高中".equals(accountType);
}
}
Loading…
Cancel
Save