刘欣睿 20250928 1556 #1

Merged
hnu202326010225 merged 0 commits from develop into main 5 months ago

@ -1,3 +0,0 @@
# 数学试卷生成器
## 软件2302刘欣睿

@ -0,0 +1,17 @@
# 数学卷子生成器
## 项目结构
MathExanGenerater/
├─ doc/
 └─ README.md
└── src/
 ├─ Generator/
   ├─ QuestionGenerator
   ├─ PrimaryGenerator
   ├─ middleGenerator
   └── highGenerator
 ├─ Account
 ├─ FileManager
 └── Main

@ -0,0 +1,23 @@
// 账户信息类
public class Account {
private String username;
private String password;
private String type; // 小学、初中、高中
public Account(String username, String password, String type) {
this.username = username;
this.password = password;
this.type = type;
}
// getters
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getType() {
return type;
}
}

@ -0,0 +1,78 @@
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Scanner;
// 文件管理器类
public class FileManager {
private String baseDir = "exam_papers";
public FileManager() {
// 创建基础目录
File dir = new File(baseDir);
if ( !dir.exists() ) {
dir.mkdir();
}
}
// 为用户创建文件夹
private String getUserDir(String username) {
String userDir = baseDir + File.separator + username;
File dir = new File(userDir);
if ( !dir.exists() ) {
dir.mkdir();
}
return userDir;
}
// 生成文件名
private String generateFileName() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
return sdf.format( new Date() ) + ".txt";
}
// 保存题目到文件
public void saveQuestions(String username, List<String> questions) throws IOException {
String userDir = getUserDir(username);
String fileName = generateFileName();
String filePath = userDir + File.separator + fileName;
try (PrintWriter writer = new PrintWriter(new FileWriter(filePath))) {
for (int i = 0; i < questions.size(); i++) {
writer.println((i + 1) + ". " + questions.get(i));
if (i < questions.size() - 1) {
writer.println(); // 题目之间空一行
}
}
}
System.out.println("题目已保存到: " + filePath);
}
// 检查题目是否重复(简化版,实际应该更复杂的比较)
public boolean isQuestionDuplicate(String username, String question) {
String userDir = getUserDir(username);
File dir = new File(userDir);
File[] files = dir.listFiles();
if (files == null) return false;
for (File file : files) {
try (Scanner scanner = new Scanner(file)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
if (line.contains(question)) {
return true;
}
}
} catch (IOException e) {
// 忽略读取错误
}
}
return false;
}
}

@ -0,0 +1,22 @@
package Generator;
public class PrimaryGenerator extends QuestionGenerator{
public PrimaryGenerator() {
super("小学");
}
@Override
public String generateQuestion() {
int operandCount = random.nextInt(4) + 2;
// 生成操作数
int[] operands = new int[operandCount];
for (int i = 0; i < operandCount; i++) {
operands[i] = random.nextInt(100) + 1; // 1-100
}
String question = preForOper(operands);
return addParen(question);
}
}

@ -0,0 +1,142 @@
package Generator;
import java.util.Random;
public abstract class QuestionGenerator{
protected Random random = new Random();
public abstract String generateQuestion() ;
protected String type;
public String getType() {
return type;
}
QuestionGenerator() {
type = "无";
}
QuestionGenerator(String Type) {
type = Type;
}
protected String preForOper(int[] operands) {
StringBuilder question = new StringBuilder();
String[] operators = {"+", "-", "×", "÷"};
question.append(operands[0]);
for (int i = 1; i < operands.length; i++) {
String op = operators[ random.nextInt (operators.length)];
question.append(" ").append(op).append(" ").append(operands[i]);
}
return question.toString();
}
protected boolean Check_num(String expression) {
if(!(expression.equals("+") || expression.equals("-") || expression.equals("×") || expression.equals("÷"))) {
return true;
}
else{
return false;
}
}
protected String addParen(String expression) {
String[] parts = expression.split(" ");
StringBuilder result = new StringBuilder();
boolean r_paren_needed = false;
for (int i = 0; i < parts.length; i++) {
if(Check_num ( parts [i]) ) {
if( !r_paren_needed ) {
if(i <= parts.length -3 )
{
if( random.nextBoolean() )
{ result.append("(");r_paren_needed = true;}
}
result.append(parts[i]);
} else {
result.append( parts [i]);
if( !random.nextBoolean()) {
result.append(")");r_paren_needed = false;
}
}
} else {
result.append( parts [i] );
}
if( i < parts.length -1 ) {
result.append(" ");
}
}
if( r_paren_needed ){
result.append(")");r_paren_needed = false;
}
return result.toString();
}
protected String add_squs(String expression) {
String[] parts = expression.split(" ");
StringBuilder result = new StringBuilder();
boolean has_squs = false;
for (int i = 0; i < parts.length; i++) {
if( Check_num( parts [i] )) {
double Thres = 0.3;
if( !has_squs){
Thres = 0.7;
}
if ( random.nextDouble() < Thres ||(i == parts.length -1 && !has_squs)) {
if ( random.nextBoolean() ) {
result.append(parts[i]);
result.append("²");
has_squs = true;
} else {
result.append("√");
result.append(parts[i]);
has_squs = true;
}
} else {
result.append(parts[i]);
}
} else {
result.append(parts[i]);
}
if( i < parts.length -1 ) {
result.append(" ");
}
}
return result.toString();
}
protected String add_sins(String expression) {
String[] parts = expression.split(" ");
StringBuilder result = new StringBuilder();
String[] functions = {"sin", "cos", "tan", "log"};
boolean has_func = false;
for (int i = 0; i < parts.length; i++) {
double Thres = 0.4;
if(!has_func){Thres = 0.8;}
if(Check_num(parts[i]))
{
if ( random.nextDouble() < Thres ||(i == parts.length-1 && !has_func) ) {
String func = functions[random.nextInt(functions.length)];
result.append(func).append("(").append(parts[i]).append(")");
} else {
result.append(parts[i]);
}
} else {
result.append(parts[i]);
}
if( i < parts.length-1 ) {
result.append(" ");
}
}
return result.toString();
}
}

@ -0,0 +1,24 @@
package Generator;
public class highGenerator extends QuestionGenerator{
public highGenerator() {
super("高中");
}
@Override
public String generateQuestion() {
int operandCount = random.nextInt(4) + 2;
// 生成操作数
int[] operands = new int[ operandCount ];
for (int i = 0; i < operandCount; i++) {
operands[i] = random.nextInt(100) + 1; // 1-100
}
String question = preForOper( operands );
question = add_squs( question );
question = add_sins( question );
return addParen( question );
}
}

@ -0,0 +1,23 @@
package Generator;
public class middleGenerator extends QuestionGenerator{
public middleGenerator() {
super("初中");
}
@Override
public String generateQuestion() {
int operandCount = random.nextInt(4) + 2;
// 生成操作数
int[] operands = new int [ operandCount ];
for (int i = 0; i < operandCount; i++) {
operands[i] = random.nextInt(100) + 1; // 1-100
}
String question = preForOper(operands);
question = add_squs(question);
return addParen(question);
}
}

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: MathExamGenerator

@ -0,0 +1,181 @@
import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;
import Generator.*;
class MathExamGenerator {
private static List<Account> accounts = new ArrayList<>();
private static Scanner scanner = new Scanner(System.in);
private static QuestionGenerator QuestionGenerator = new PrimaryGenerator();
private static FileManager fileManager = new FileManager();
private static Account currentAccount = null;
// 初始化账户数据
static {
// 小学账户
accounts.add(new Account("张三1", "123", "小学"));
accounts.add(new Account("张三2", "123", "小学"));
accounts.add(new Account("张三3", "123", "小学"));
// 初中账户
accounts.add(new Account("李四1", "123", "初中"));
accounts.add(new Account("李四2", "123", "初中"));
accounts.add(new Account("李四3", "123", "初中"));
// 高中账户
accounts.add(new Account("王五1", "123", "高中"));
accounts.add(new Account("王五2", "123", "高中"));
accounts.add(new Account("王五3", "123", "高中"));
}
public static void main(String[] args) {
System.out.println("=== 中小学数学卷子自动生成程序 ===");
while (true) {
if (currentAccount == null) {
login();
} else {
generateExam();
}
}
}
// 登录功能
private static void login() {
while (true) {
System.out.print("请输入用户名和密码用空格隔开输入exit退出程序: ");
String input = scanner.nextLine().trim();
if (input.equalsIgnoreCase("exit")) {
System.exit(0);
}
String[] credentials = input.split(" ");
if (credentials.length != 2) {
System.out.println("请输入正确的用户名、密码格式(用户名 密码)");
continue;
}
String username = credentials[0];
String password = credentials[1];
for (Account account : accounts) {
if (account.getUsername().equals(username) && account.getPassword().equals(password)) {
currentAccount = account;
if( account.getType().equals("小学") ) {
QuestionGenerator = new PrimaryGenerator();
}
else if( account.getType().equals("初中") ) {
QuestionGenerator = new middleGenerator();
}
else if( account.getType().equals("高中") ) {
QuestionGenerator = new highGenerator();
}
// QuestionGenerator = new QuestionGenerator(account.getType());
System.out.println("当前选择为 " + QuestionGenerator.getType() + " 出题");
return;
}
}
System.out.println("请输入正确的用户名、密码");
}
}
// 生成试卷功能
private static void generateExam() {
while (true) {
System.out.print("准备生成 " + QuestionGenerator.getType() +
" 数学题目请输入生成题目数量10-30输入-1退出当前用户输入'switch'切换类型): ");
String input = scanner.nextLine().trim();
if ( input.equals("-1") ) {
currentAccount = null;
return;
}
if ( input.startsWith("切换为") ) {
handleSwitchType(input);
continue;
}
if ( input.equalsIgnoreCase("switch" )) {
System.out.print("请输入要切换的类型(小学/初中/高中): ");
String typeInput = scanner.nextLine().trim();
handleSwitchType("切换为 " + typeInput);
continue;
}
try {
int count = Integer.parseInt(input);
if (count >= 10 && count <= 30) {
generateQuestions(count);
} else {
System.out.println("题目数量必须在10-30之间");
}
} catch (NumberFormatException e) {
System.out.println("请输入有效的数字10-30或-1退出");
}
}
}
// 处理类型切换
private static void handleSwitchType(String input) {
Pattern pattern = Pattern.compile("切换为\\s*(小学|初中|高中)");
var matcher = pattern.matcher(input);
if ( matcher.matches() ) {
String newType = matcher.group(1);
if( newType.equals("小学") ) {
QuestionGenerator = new PrimaryGenerator();
}
else if( newType.equals("初中") ) {
QuestionGenerator = new middleGenerator();
}
else if( newType.equals("高中") ) {
QuestionGenerator = new highGenerator();
}
//else{ QuestionGenerator = new highGenerator();}
// QuestionGenerator.setType(newType);
// currentAccount.SetType(newType);
System.out.println("已切换为 " + QuestionGenerator.getType() + " 出题");
//System.out.print("准备生成 " + newType + " 数学题目,请输入生成题目数量: ");
} else {
System.out.println("请输入小学、初中和高中三个选项中的一个");
}
}
// 生成题目
private static void generateQuestions(int count) {
List<String> questions = new ArrayList<>();
Set<String> generatedQuestions = new HashSet<>();
for (int i = 0; i < count; i++) {
String question;
int attempt = 0;
// 尝试生成不重复的题目
do {
question = QuestionGenerator.generateQuestion();
attempt++;
// 防止无限循环
if ( attempt > 100 ) {
System.out.println("警告:无法生成足够的不重复题目,可能重复率较高");
break;
}
} while ( generatedQuestions.contains(question ) ||
fileManager.isQuestionDuplicate(currentAccount.getUsername(), question));
generatedQuestions.add(question);
questions.add(question);
}
try {
fileManager.saveQuestions(currentAccount.getUsername(), questions);
System.out.println("成功生成 " + count + " 道题目");
} catch ( IOException e ) {
System.out.println("保存文件时出错: " + e.getMessage());
}
}
}
Loading…
Cancel
Save