Initial commit

pull/1/head
hnu202326010307 7 months ago committed by Nie
parent 424c0e7985
commit 7d592fdede

@ -0,0 +1,7 @@
{
"java.project.sourcePaths": ["src"],
"java.project.outputPath": "bin",
"java.project.referencedLibraries": [
"lib/**/*.jar"
]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,19 @@
1. ((36 * 25) * 51 - 30)
2. 100 - 18 / 38
3. ((((5 - 55) - 9) - 35) * 30)
4. (8 - 100 - 52)
5. (((74 - 67) - 87) * 10)
6. ((44 + 61 * 49) * 16)
7. ((99 - 3 + 46) - 14 / 71)
8. 38 - 62 + 37
9. 81 / 27
10. (((44 + 8) / 88) - 72)

@ -0,0 +1,19 @@
1. (√81 / 67 / 42) + 78 + 54
2. √88 / 55 / 14
3. (41 * 45) - √78
4. (((49² - 37) - 73 / 47) - 56) - 37
5. (√11 + 29 / 60)
6. (((((√59 * 22) + 12) - 8) - 60) - 3)
7. ((2² + 37) - 32)
8. 5 / 57²
9. √31 / 47
10. ((27 + 26) / 49 * 4) / 85²

@ -0,0 +1,19 @@
1. ((89 * sin(268°) - 86) - tan(279°) / tan(85°) + 45)
2. 1 - sin(359°)
3. (41 / 60 * tan(48°) / 14) + tan(188°)
4. 66 + tan(135°)
5. (tan(250°) * tan(106°) / 62 * 55) + sin(25°) * tan(99°)
6. 41 - 20 / sin(221°)
7. 48 / tan(229°) + cos(250°) - tan(287°) - 28
8. (38 + 29) / cos(103°)
9. 25 + tan(231°)
10. (((84 * 93) * 17 * 82) / sin(321°) + 28)

@ -0,0 +1,19 @@
1. (√32 - 95 * 46 / 56 + 60) - 92
2. ((72 - 3 + 15) * 85) / √86
3. ((16² * 58 + 53) + 17 - 9) + 87
4. (√64 * 96) + 68
5. (45 * 50) / √48
6. ((49² - 35 + 24) / 89) + 50
7. ((√91 / 19) / 53)
8. (√65 + 73) + 76
9. 9 - 13²
10. 22² - 68

@ -0,0 +1,45 @@
1. 34 - 93
2. 41 / 27
3. (89 / 38 / 28)
4. (69 - 61) - 15 / 79
5. ((67 * 80 + 33) - 48) * 17
6. (15 + 36 / 59 / 34)
7. 57 * 58 + 28
8. (48 - 100 + 17 + 64)
9. (77 / 99) + 1
10. ((77 + 20 - 37 / 60) + 45 / 28)
11. ((47 + 22) / 34 + 11)
12. 40 + 68
13. 49 - 50 * 76 + 64
14. ((69 - 4) - 80 / 15 * 28)
15. ((35 / 99) * 20)
16. (15 * 26 - 42) * 17 * 65 + 40
17. 68 + 13
18. (94 + 76 * 65 - 1 - 71)
19. ((86 + 92) + 91 + 53)
20. (95 - 99) * 42 + 17 / 71
21. 22 + 42
22. ((((42 / 96) - 6) / 7) / 2) / 57
23. (((27 * 83) - 37) + 16)

@ -0,0 +1,252 @@
package src;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class App {
private static final Scanner scanner = new Scanner(System.in);
private static final Map<String, User> users = User.getPresetUsers();
private static final FileManager fileManager = new FileManager();
private static QuestionGenerator currentGenerator;
private static String currentUsername;
public static void main(String[] args) {
System.out.println("=== 中小学数学卷子自动生成程序 ===");
while (true) {
// 登录
User loggedInUser = login();
currentUsername = loggedInUser.getUsername();
String userType = loggedInUser.getUserType();
// 根据用户类型初始化题目生成器
switch (userType) {
case "小学":
currentGenerator = new PrimarySchoolGenerator();
break;
case "初中":
currentGenerator = new MiddleSchoolGenerator();
break;
case "高中":
currentGenerator = new HighSchoolGenerator();
break;
}
System.out.println("当前选择为 " + userType + " 出题");
// 加载已存在的题目用于查重
Set<String> existingQuestions = fileManager.loadExistingQuestions(currentUsername);
for (String question : existingQuestions) {
currentGenerator.addToGenerated(question);
}
// 主循环
boolean stayLoggedIn = true;
while (stayLoggedIn) {
System.out.println("\n准备生成 " + currentGenerator.getCurrentType() + " 数学题目,请输入生成题目数量(输入-1将退出当前用户重新登录");
String input = scanner.nextLine().trim();
if (input.equals("-1")) {
stayLoggedIn = false;
System.out.println("退出当前用户...");
break;
}
// 处理切换类型命令
if (input.startsWith("切换为")) {
handleTypeSwitch(input);
continue;
}
// 生成题目
try {
int count = Integer.parseInt(input);
if (count >= 10 && count <= 30) {
generateAndSaveQuestions(count);
} else {
System.out.println("题目数量必须在10-30之间请重新输入。");
}
} catch (NumberFormatException e) {
System.out.println("请输入有效的数字10-30或'切换为XX'命令。");
}
}
}
}
private static User login() {
while (true) {
System.out.println("\n请输入用户名和密码用空格隔开");
System.out.println("如果需要注册新用户,请输入'register'");
System.out.println("如果需要退出程序,请输入'-1'");
String input = scanner.nextLine();
String[] credentials = input.split("\\s+");
if (credentials[0].equals("-1")) {
System.out.println("退出程序...");
System.exit(0);
}
// 处理注册请求
if (credentials[0].equalsIgnoreCase("register")) {
handleRegistration();
continue;
}
if (credentials.length != 2) {
System.out.println("请输入正确的用户名、密码格式(用户名 密码)");
continue;
}
String username = credentials[0];
String password = credentials[1];
User user = User.authenticate(username, password);
if (user != null) {
return user;
} else {
System.out.println("请输入正确的用户名、密码");
}
}
}
/**
*
*/
private static void handleRegistration() {
System.out.println("\n=== 用户注册 ===");
// 输入用户名
String username;
while (true) {
System.out.print("请输入用户名: ");
username = scanner.nextLine().trim();
if (username.isEmpty()) {
System.out.println("用户名不能为空,请重新输入。");
continue;
}
if (User.userExists(username)) {
System.out.println("用户名已存在,请选择其他用户名。");
continue;
}
break;
}
// 输入密码
String password;
while (true) {
System.out.print("请输入密码: ");
password = scanner.nextLine().trim();
if (password.isEmpty()) {
System.out.println("密码不能为空,请重新输入。");
continue;
}
break;
}
// 选择用户类型
String userType;
while (true) {
System.out.println("请选择用户类型:");
System.out.println("1. 小学");
System.out.println("2. 初中");
System.out.println("3. 高中");
System.out.print("请输入选项(1-3): ");
String choice = scanner.nextLine().trim();
switch (choice) {
case "1":
userType = "小学";
break;
case "2":
userType = "初中";
break;
case "3":
userType = "高中";
break;
default:
System.out.println("无效选项,请重新选择。");
continue;
}
break;
}
// 添加用户
if (User.addUser(username, password, userType)) {
System.out.println("用户注册成功!");
System.out.println("用户名: " + username);
System.out.println("用户类型: " + userType);
System.out.println("请使用新用户登录。");
} else {
System.out.println("用户注册失败,请重试。");
}
}
private static void handleTypeSwitch(String input) {
// 提取目标类型,支持"切换为小学"和"切换为 小学"两种格式
String targetType;
if (input.contains(" ")) {
// 格式:"切换为 小学"(有空格)
String[] parts = input.split("\\s+");
if (parts.length != 2) {
System.out.println("请输入小学、初中和高中三个选项中的一个");
return;
}
targetType = parts[1];
} else {
// 格式:"切换为小学"(无空格)
targetType = input.substring(3); // 去掉"切换为"三个字
}
if (!targetType.equals("小学") && !targetType.equals("初中") && !targetType.equals("高中")) {
System.out.println("请输入小学、初中和高中三个选项中的一个");
return;
}
// 切换题目生成器
switch (targetType) {
case "小学":
currentGenerator = new PrimarySchoolGenerator();
break;
case "初中":
currentGenerator = new MiddleSchoolGenerator();
break;
case "高中":
currentGenerator = new HighSchoolGenerator();
break;
}
// 重新加载已存在的题目用于查重
Set<String> existingQuestions = fileManager.loadExistingQuestions(currentUsername);
for (String question : existingQuestions) {
currentGenerator.addToGenerated(question);
}
System.out.println("已切换为 " + targetType + " 出题模式");
}
private static void generateAndSaveQuestions(int count) {
String[] questions = new String[count];
System.out.println("正在生成 " + count + " 道 " + currentGenerator.getCurrentType() + " 题目...");
for (int i = 0; i < count; i++) {
questions[i] = currentGenerator.generateQuestion();
System.out.println((i + 1) + ". " + questions[i]);
}
try {
fileManager.saveQuestions(currentUsername, questions);
System.out.println("题目生成完成!");
} catch (Exception e) {
System.out.println("保存文件时出错: " + e.getMessage());
}
}
}

@ -0,0 +1,98 @@
package src;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class FileManager {
private String baseDir;
public FileManager() {
this.baseDir = System.getProperty("user.dir") + File.separator + "papers";
createBaseDirectory();
}
// 创建基础目录
private void createBaseDirectory() {
File dir = new File(baseDir);
if (!dir.exists()) {
dir.mkdirs();
}
}
// 为用户创建目录
private String createUserDirectory(String username) {
String userDir = baseDir + File.separator + username;
File dir = new File(userDir);
if (!dir.exists()) {
dir.mkdirs();
}
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, String[] questions) throws IOException {
String userDir = createUserDirectory(username);
String fileName = generateFileName();
String filePath = userDir + File.separator + fileName;
try (PrintWriter writer = new PrintWriter(new FileWriter(filePath))) {
for (int i = 0; i < questions.length; i++) {
writer.println((i + 1) + ". " + questions[i]);
if (i < questions.length - 1) {
writer.println(); // 题目之间空一行
}
}
}
System.out.println("题目已保存到: " + filePath);
}
// 检查题目是否重复(读取用户目录下所有文件)
public Set<String> loadExistingQuestions(String username) {
Set<String> existingQuestions = new HashSet<>();
String userDir = baseDir + File.separator + username;
File dir = new File(userDir);
if (dir.exists() && dir.isDirectory()) {
File[] files = dir.listFiles((d, name) -> name.endsWith(".txt"));
if (files != null) {
for (File file : files) {
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
StringBuilder questionBuilder = new StringBuilder();
while ((line = reader.readLine()) != null) {
if (line.trim().isEmpty()) {
if (questionBuilder.length() > 0) {
// 移除题号
String question = questionBuilder.toString().replaceAll("^\\d+\\.\\s*", "");
existingQuestions.add(question.trim());
questionBuilder.setLength(0);
}
} else {
questionBuilder.append(line).append(" ");
}
}
// 处理最后一个题目
if (questionBuilder.length() > 0) {
String question = questionBuilder.toString().replaceAll("^\\d+\\.\\s*", "");
existingQuestions.add(question.trim());
}
} catch (IOException e) {
System.out.println("读取文件失败: " + file.getName());
}
}
}
}
return existingQuestions;
}
}

@ -0,0 +1,85 @@
package src;
public class HighSchoolGenerator extends QuestionGenerator {
private static final String[] BASIC_OPERATORS = {"+", "-", "*", "/"};
private static final String[] TRIG_FUNCTIONS = {"sin", "cos", "tan"};
public HighSchoolGenerator() {
super("高中");
}
@Override
public String generateQuestion() {
String question;
do {
question = generateSingleQuestion();
} while (isDuplicate(question) || !question.matches(".*(sin|cos|tan)\\(.*\\).*")); // 确保包含三角函数
addToGenerated(question);
return question;
}
private String generateSingleQuestion() {
int operatorCount = generateOperatorCount();
StringBuilder questionBuilder = new StringBuilder();
boolean hasTrigFunction = false;
// 生成第一个操作数或三角函数
hasTrigFunction = processFirstOperandOrTrig(questionBuilder);
// 生成操作符和操作数
processOperatorsAndOperands(questionBuilder, operatorCount, hasTrigFunction);
return questionBuilder.toString();
}
private boolean processFirstOperandOrTrig(StringBuilder builder) {
if (random.nextBoolean()) {
// 使用三角函数
String trigFunction = TRIG_FUNCTIONS[random.nextInt(TRIG_FUNCTIONS.length)];
int angle = random.nextInt(360) + 1; // 1-360度
builder.append(trigFunction).append("(").append(angle).append("°)");
return true;
} else {
// 使用普通数字
builder.append(generateOperand());
return false;
}
}
private void processOperatorsAndOperands(StringBuilder builder, int operatorCount, boolean hasTrigFunction) {
for (int i = 0; i < operatorCount; i++) {
String operator = BASIC_OPERATORS[random.nextInt(BASIC_OPERATORS.length)];
// 决定下一个操作数是普通数字还是三角函数
if (!hasTrigFunction && i == operatorCount - 1) {
// 确保至少有一个三角函数
appendTrigFunction(builder, operator);
hasTrigFunction = true;
} else if (random.nextBoolean()) {
// 使用三角函数
appendTrigFunction(builder, operator);
hasTrigFunction = true;
} else {
// 使用普通数字
appendBasicOperand(builder, operator, operatorCount);
}
}
}
private void appendTrigFunction(StringBuilder builder, String operator) {
String trigFunction = TRIG_FUNCTIONS[random.nextInt(TRIG_FUNCTIONS.length)];
int angle = random.nextInt(360) + 1;
builder.append(" ").append(operator).append(" ").append(trigFunction).append("(").append(angle).append("°)");
}
private void appendBasicOperand(StringBuilder builder, String operator, int operatorCount) {
int operand = generateOperand();
// 随机决定是否加括号
if (random.nextBoolean() && operatorCount > 1) {
builder.insert(0, "(").append(" ").append(operator).append(" ").append(operand).append(")");
} else {
builder.append(" ").append(operator).append(" ").append(operand);
}
}
}

@ -0,0 +1,95 @@
package src;
public class MiddleSchoolGenerator extends QuestionGenerator {
private static final String[] BASIC_OPERATORS = {"+", "-", "*", "/"};
private static final String[] ADVANCED_OPERATORS = {"²", "√"};
public MiddleSchoolGenerator() {
super("初中");
}
@Override
public String generateQuestion() {
String question;
do {
question = generateSingleQuestion();
} while (isDuplicate(question) || !question.matches(".*[²√].*")); // 确保包含高级运算符
addToGenerated(question);
return question;
}
private String generateSingleQuestion() {
int operatorCount = generateOperatorCount();
StringBuilder questionBuilder = new StringBuilder();
boolean hasAdvancedOperator = false;
// 生成第一个操作数
int firstOperand = generateOperand();
// 处理第一个操作数(可能使用高级运算符)
hasAdvancedOperator = processFirstOperand(questionBuilder, firstOperand);
// 生成操作符和操作数
processOperatorsAndOperands(questionBuilder, operatorCount, hasAdvancedOperator);
return questionBuilder.toString();
}
private boolean processFirstOperand(StringBuilder builder, int operand) {
// 随机决定第一个操作数是否使用高级运算符
if (random.nextBoolean()) {
String advancedOp = ADVANCED_OPERATORS[random.nextInt(ADVANCED_OPERATORS.length)];
if (advancedOp.equals("²")) {
builder.append(operand).append("²");
} else {
builder.append("√").append(operand);
}
return true;
} else {
builder.append(operand);
return false;
}
}
private void processOperatorsAndOperands(StringBuilder builder, int operatorCount, boolean hasAdvancedOperator) {
for (int i = 0; i < operatorCount; i++) {
String operator = determineOperator(i, operatorCount, hasAdvancedOperator);
int operand = generateOperand();
if (operator.equals("²") || operator.equals("√")) {
processAdvancedOperator(builder, operator, operand);
hasAdvancedOperator = true;
} else {
processBasicOperator(builder, operator, operand, operatorCount);
}
}
}
private String determineOperator(int currentIndex, int totalOperators, boolean hasAdvancedOperator) {
if (!hasAdvancedOperator && currentIndex == totalOperators - 1) {
// 确保至少有一个高级运算符
return ADVANCED_OPERATORS[random.nextInt(ADVANCED_OPERATORS.length)];
} else {
return BASIC_OPERATORS[random.nextInt(BASIC_OPERATORS.length)];
}
}
private void processAdvancedOperator(StringBuilder builder, String operator, int operand) {
String basicOp = BASIC_OPERATORS[random.nextInt(BASIC_OPERATORS.length)];
if (operator.equals("²")) {
builder.append(" ").append(basicOp).append(" ").append(operand).append("²");
} else {
builder.append(" ").append(basicOp).append(" √").append(operand);
}
}
private void processBasicOperator(StringBuilder builder, String operator, int operand, int operatorCount) {
// 随机决定是否加括号
if (random.nextBoolean() && operatorCount > 1) {
builder.insert(0, "(").append(" ").append(operator).append(" ").append(operand).append(")");
} else {
builder.append(" ").append(operator).append(" ").append(operand);
}
}
}

@ -0,0 +1,40 @@
package src;
public class PrimarySchoolGenerator extends QuestionGenerator {
private static final String[] OPERATORS = {"+", "-", "*", "/"};
public PrimarySchoolGenerator() {
super("小学");
}
@Override
public String generateQuestion() {
String question;
do {
int operatorCount = generateOperatorCount();
StringBuilder questionBuilder = new StringBuilder();
// 生成第一个操作数
questionBuilder.append(generateOperand());
// 生成操作符和操作数
for (int i = 0; i < operatorCount; i++) {
String operator = OPERATORS[random.nextInt(OPERATORS.length)];
int operand = generateOperand();
// 随机决定是否加括号
if (random.nextBoolean() && operatorCount > 1) {
questionBuilder.insert(0, "(").append(" " + operator + " " + operand + ")");
} else {
questionBuilder.append(" " + operator + " " + operand);
}
}
question = questionBuilder.toString();
} while (isDuplicate(question));
addToGenerated(question);
return question;
}
}

@ -0,0 +1,49 @@
package src;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public abstract class QuestionGenerator {
protected Random random = new Random();
protected Set<String> generatedQuestions = new HashSet<>();
protected String currentType;
public QuestionGenerator(String type) {
this.currentType = type;
}
// 生成操作数
protected int generateOperand() {
return random.nextInt(100) + 1; // 1-100
}
// 生成操作符数量
protected int generateOperatorCount() {
return random.nextInt(5) + 1; // 1-5个操作符
}
// 检查题目是否重复
protected boolean isDuplicate(String question) {
return generatedQuestions.contains(question);
}
// 添加题目到已生成集合
protected void addToGenerated(String question) {
generatedQuestions.add(question);
}
// 抽象方法:生成题目
public abstract String generateQuestion();
// 获取当前类型
public String getCurrentType() {
return currentType;
}
// 设置当前类型
public void setCurrentType(String type) {
this.currentType = type;
this.generatedQuestions.clear(); // 切换类型时清空已生成题目
}
}

@ -0,0 +1,138 @@
package src;
import java.util.HashMap;
import java.util.Map;
public class User {
private String username;
private String password;
private String userType; // 小学、初中、高中
// 静态用户映射,用于存储所有用户
private static Map<String, User> userMap = getPresetUsers();
public User(String username, String password, String userType) {
this.username = username;
this.password = password;
this.userType = userType;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getUserType() {
return userType;
}
// 用户管理接口
/**
*
* @param username
* @param password
* @param userType
* @return truefalse
*/
public static boolean addUser(String username, String password, String userType) {
if (userMap.containsKey(username)) {
return false; // 用户名已存在
}
userMap.put(username, new User(username, password, userType));
return true;
}
/**
*
* @param username
* @return truefalse
*/
public static boolean removeUser(String username) {
if (!userMap.containsKey(username)) {
return false; // 用户不存在
}
userMap.remove(username);
return true;
}
/**
*
* @param username
* @return truefalse
*/
public static boolean userExists(String username) {
return userMap.containsKey(username);
}
/**
*
* @param username
* @param password
* @return Usernull
*/
public static User authenticate(String username, String password) {
User user = userMap.get(username);
if (user != null && user.getPassword().equals(password)) {
return user;
}
return null;
}
/**
*
* @return
*/
public static int getUserCount() {
return userMap.size();
}
/**
*
* @param userType
* @return
*/
public static int getUserCountByType(String userType) {
int count = 0;
for (User user : userMap.values()) {
if (user.getUserType().equals(userType)) {
count++;
}
}
return count;
}
/**
*
* @param username
* @return Usernull
*/
public static User getUser(String username) {
return userMap.get(username);
}
// 预设用户数据
public static Map<String, User> getPresetUsers() {
Map<String, User> users = new HashMap<>();
// 小学用户
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", "高中"));
return users;
}
}
Loading…
Cancel
Save