develop to main #1

Merged
psoyzuart merged 30 commits from develop into main 4 months ago

@ -1,2 +0,0 @@
# individual

@ -0,0 +1,265 @@
# **中小学数学卷子自动生成程序说明**
## 一、概述
该项目是一个基于 Java 的中小学数学卷子自动生成系统,支持小学、初中和高中三个难度级别,具备用户登录、题目生成、查重、文件存储等功能。
## 二、类
### 1.Start - 程序入口类
#### **功能:**
程序的启动入口,调用 Login 类启动登录流程。
#### **方法:**
main(String[] args) 启动程序,创建 Login 实例并调用其 Main() 方法。
### 2. Login - 用户登录类
#### **功能:**
处理用户登录、验证、权限管理和难度切换。
#### **方法:**
Main() 主登录循环,接收用户输入并验证。
initializeUserFile() 初始化用户文件 users.txt如果不存在则创建。
load() 从 users.txt 加载用户信息到内存。
Prove(String username, String password) 验证用户名和密码。
Success(User user, Scanner scanner) 登录成功后进入题目生成流程。
Switch(QuestionManager questionManager, String input) 切换题目生成难度。
getRole(String role):将英文角色转换为中文显示。
### 3. User - 用户信息类
#### **功能:**
封装用户的基本信息。
#### **属性:**
username 用户名
password 密码
role 角色primary/junior/senior
#### **方法:**
构造方法和 getter 方法
### 4. QuestionManager - 题目管理器
#### **功能:**
管理题目生成、文件存储和用户目录。
#### **方法:**
setRole(String role) 设置当前题目生成器(小学/初中/高中)。
createQuestionsDirectory() 创建用户题目存储目录。
generateQuestions(int count) 生成指定数量的题目并保存到文件。
getCurrentRoleChinese() 返回当前难度的中文名称。
getUserQuestionFiles(String username) 获取用户所有题目文件(用于查重)。
### 5. QuestionGenerator - 题目生成器接口
#### **功能:**
定义题目生成器的基本行为。
#### **方法:**
generateQuestion() 生成一道题目。
normalizeQuestion(String question) 标准化题目格式用于比较。
generateOperator(String[] operators) 随机生成运算符。
isValidParentheses(String expression) 验证括号是否合法。
### 6. AbstractQuestionGenerator - 抽象题目生成器
#### **功能:**
提供题目生成的通用方法和查重机制。
#### **方法:**
setUsername(String username) 设置用户名并加载历史题目。
loadExistingQuestions() 加载用户已生成的题目用于查重。
normalizeQuestion(String question) 去除空格标准化题目。
generateNumber() 生成 1~100 的随机数。
isQuestionUnique(String question) 判断题目是否重复。
isValidParentheses(String expression) 验证括号是否合法且不冗余。
ensureBalancedParentheses(String expression) 确保括号成对出现。
### 7. PrimaryQuestionGenerator - 小学题目生成器
#### **功能:**
生成小学难度题目,仅包含加减乘除和括号。
#### **方法:**
generateQuestion() 生成小学题目,支持括号和多个操作数。
addReasonableParentheses(String expression, int operandCount) 随机添加合理括号。
### 8. JuniorQuestionGenerator - 初中题目生成器
#### **功能:**
生成初中难度题目,至少包含一个平方或开方运算。
#### **方法:**
generateQuestion() 生成初中题目,确保包含平方或开方。
AddSpecialOperator(...) 添加平方或开方运算符。
hasProperOperatorSpacing(String expression) 检查运算符间距是否合理。
### 9. SeniorQuestionGenerator - 高中题目生成器
#### **功能:**
生成高中难度题目至少包含一个三角函数sin/cos/tan支持嵌套。
#### **方法:**
generateQuestion() 生成高中题目,确保包含三角函数。
AddTrigOperator(...) 添加三角函数运算符。
ForceAddTrigOperator(...) 若未包含三角函数,则强制添加。
Revise(String expression) 调整括号位置,避免语法错误。
## 三、流程
### 1.登录流程
1用户输入用户名和密码
2系统验证身份并显示角色
3用户选择生成题目数量或切换难度
4系统生成题目并保存到用户目录。
### 2.题目生成流程
1根据难度选择对应的生成器
2生成操作数和运算符
3添加括号和特殊运算符初中/高中);
4查重和括号合法性检查
5保存到文件格式为 年-月-日-时-分-秒.txt。
### 3.文件存储结构
src
├── questions/
| └── 用户名/
| ├── 2025-09-20-10-30-45.txt
| └── 2025-09-20-10-35-22.txt
└── users.txt
### 4.难度特征
|难度| 运算符类型| 特殊要求|
|:---:|:---|:---|
|小学| +, -, ×, ÷| 可含括号|
|初中| +, -, ×, ÷, ², √| 至少一个平方或开方|
|高中| +, -, ×, ÷, sin, cos, tan| 至少一个三角函数,可嵌套|
## 四、运行
### 1. Linux bash
```bash
~/src$ javac *.java
~/src$ java Start
已创建users.txt
Loading...
---------登录系统---------
请输入用户名和密码(用空格隔开):
```
或先生成jar
```bash
~/src$ javac *.java
~/src$ jar -cfve main.jar Start *.class
已添加清单
正在添加: AbstractQuestionGenerator.class(输入 = 4777) (输出 = 2649)(压缩了 44%)
正在添加: JuniorQuestionGenerator.class(输入 = 3654) (输出 = 2095)(压缩了 42%)
正在添加: Login.class(输入 = 5877) (输出 = 3401)(压缩了 42%)
正在添加: PrimaryQuestionGenerator.class(输入 = 2048) (输出 = 1203)(压缩了 41%)
正在添加: QuestionGenerator.class(输入 = 356) (输出 = 199)(压缩了 44%)
正在添加: QuestionManager.class(输入 = 4097) (输出 = 2204)(压缩了 46%)
正在添加: SeniorQuestionGenerator.class(输入 = 4577) (输出 = 2454)(压缩了 46%)
正在添加: Start.class(输入 = 308) (输出 = 238)(压缩了 22%)
正在添加: User.class(输入 = 1121) (输出 = 540)(压缩了 51%)
~/src$ java -jar main
Error: Unable to access jarfile main
~/src$ java -jar main.jar
已创建users.txt
Loading...
---------登录系统---------
请输入用户名和密码(用空格隔开):
```
### 2.Windows cmd
```cmd
D:\src>chcp 65001
Active code page: 65001
D:\src>java Start.java
已创建users.txt
Loading...
---------登录系统---------
请输入用户名和密码(用空格隔开):
```
```cmd
D:\src>chcp 65001
Active code page: 65001
D:\src>javac -encoding UTF-8 *.java
D:\src>java Start
已创建users.txt
Loading...
---------登录系统---------
请输入用户名和密码(用空格隔开):
```
或先生成jar
```cmd
D:\src>chcp 65001
Active code page: 65001
D:\src>javac -encoding UTF-8 *.java
D:\src>jar cfve main.jar Start *.class
已添加清单
正在添加: AbstractQuestionGenerator.class(输入 = 4777) (输出 = 2647)(压缩了 44%)
正在添加: JuniorQuestionGenerator.class(输入 = 3654) (输出 = 2095)(压缩了 42%)
正在添加: Login.class(输入 = 5877) (输出 = 3402)(压缩了 42%)
正在添加: PrimaryQuestionGenerator.class(输入 = 2048) (输出 = 1203)(压缩了 41%)
正在添加: QuestionGenerator.class(输入 = 356) (输出 = 199)(压缩了 44%)
正在添加: QuestionManager.class(输入 = 4097) (输出 = 2204)(压缩了 46%)
正在添加: SeniorQuestionGenerator.class(输入 = 4577) (输出 = 2454)(压缩了 46%)
正在添加: Start.class(输入 = 308) (输出 = 238)(压缩了 22%)
正在添加: User.class(输入 = 1121) (输出 = 539)(压缩了 51%)
D:\src>java -jar main.jar
已创建users.txt
Loading...
---------登录系统---------
请输入用户名和密码(用空格隔开):
```
### 3.Windows PowerShell
与cmd类似只需将
```cmd
D:\src>chcp 65001
```
换成
```powershell
PS D:\src> [Console]::InputEncoding = [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
```

@ -0,0 +1,134 @@
import java.io.*;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.Stack;
public abstract class AbstractQuestionGenerator implements QuestionGenerator {
protected Random random = new Random();
protected Set<String> generatedQuestions = new HashSet<>();
protected String username;
// 设置用户名用于查重
public void setUsername(String username) {
this.username = username;
loadExistingQuestions();
}
// 从文件中加载已存在的题目
protected void loadExistingQuestions() {
if (username == null) return;
File[] userFiles = QuestionManager.getUserQuestionFiles(username);
for (File file : userFiles) {
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (!line.isEmpty() && line.matches("^\\d+\\. .+")) {
// 提取题目内容(去除题号)
String question = line.replaceFirst("^\\d+\\. ", "");
String normalized = normalizeQuestion(question);
generatedQuestions.add(normalized);
}
}
} catch (IOException e) {
System.out.println("读取题目文件出错: " + e.getMessage());
}
}
}
// 标准化题目格式用于比较
public String normalizeQuestion(String question) {
return question.replaceAll("\\s+", "");
}
protected String generateNumber() {
return String.valueOf(random.nextInt(100) + 1);
}
public String generateOperator(String[] operators) {
return operators[random.nextInt(operators.length)];
}
protected boolean isQuestionUnique(String question) {
String normalized = normalizeQuestion(question);
return !generatedQuestions.contains(normalized);
}
protected void addToGeneratedQuestions(String question) {
String normalized = normalizeQuestion(question);
generatedQuestions.add(normalized);
}
protected boolean hasBalancedParentheses(String expression) {
Stack<Character> stack = new Stack<>();
for (char c : expression.toCharArray()) {
if (c == '(') {
stack.push(c);
} else if (c == ')') {
if (stack.isEmpty()) return false;
stack.pop();
}
}
return stack.isEmpty();
}
public boolean isValidParentheses(String expression) {
expression = expression.replaceAll("\\s+", "");
if (!hasBalancedParentheses(expression)) {
return false;
}
if (expression.startsWith("(") && expression.endsWith(")") &&
hasBalancedParentheses(expression.substring(1, expression.length() - 1))) {
return false;
}
String[] parts = expression.split("[+\\-×÷]");
for (String part : parts) {
part = part.trim();
if (part.startsWith("(") && part.endsWith(")")) {
String inside = part.substring(1, part.length() - 1);
if (isSimpleOperand(inside)) {
return false;
}
}
}
return true;
}
private boolean isSimpleOperand(String str) {
return str.matches("\\d+") || str.matches("√\\d+") || str.matches("\\d²+") ||
str.matches("sin[\\d°]+") || str.matches("cos[\\d°]+") || str.matches("tan[\\d°]+") ||
str.matches("sincos[\\d°]+") || str.matches("sintan[\\d°]+") || str.matches("cossin[\\d°]+") ||
str.matches("costan[\\d°]+") || str.matches("tansin[\\d°]+") || str.matches("tancos[\\d°]+");
}
protected boolean hasOperator(String expression) {
return expression.contains("+") || expression.contains("-") ||
expression.contains("×") || expression.contains("÷");
}
protected String ensureBalancedParentheses(String expression) {
int openCount = 0;
int closeCount = 0;
for (char c : expression.toCharArray()) {
if (c == '(') openCount++;
if (c == ')') closeCount++;
}
while (openCount > closeCount) {
expression += ")";
closeCount++;
}
return expression;
}
}

@ -0,0 +1,122 @@
public class JuniorQuestionGenerator extends AbstractQuestionGenerator {
private static final String[] OPERATORS = {"+", "-", "×", "÷"};
private static boolean h = false;
private static StringBuilder q;
@Override
public String generateQuestion() {
int attempts = 0;
while (attempts < 100) {
attempts++;
int operandCount = random.nextInt(5) + 1; // 1~5个操作数
StringBuilder question = new StringBuilder();
boolean hasSpecialOperator = false;
AddSpecialOperator(operandCount, hasSpecialOperator, question);
hasSpecialOperator = h;
question = q;
String result = addReasonableParentheses(question.toString(), operandCount);
result = ensureBalancedParentheses(result);
// 检查平方后是否有运算符
if (!hasProperOperatorSpacing(result)) {
continue;
}
if (isQuestionUnique(result) && isValidParentheses(result) &&
(hasOperator(result) || hasSpecialOperator)) {
addToGeneratedQuestions(result);
String regex = "(?<!\\s)\\)(?=[^)]*$)";
result = result.replaceAll(regex, " )");
return result;
}
}
return "√4 + 3²"; // 备用题目
}
private void AddSpecialOperator(int operandCount, boolean hasSpecialOperator, StringBuilder question) {
for (int i = 0; i < operandCount; i++) {
if (!hasSpecialOperator && random.nextDouble() < 0.4) {// 决定是否添加特殊运算符(平方或开方)
if (random.nextBoolean()) {
question.append(generateNumber()).append("²");
} else {
question.append("√").append(generateNumber());
}
hasSpecialOperator = true;
} else {
question.append(generateNumber());
}
if (i < operandCount - 1) {
String operator = generateOperator(OPERATORS);
question.append(" ").append(operator).append(" ");
}
}
if (!hasSpecialOperator) {// 如果还没有特殊运算符,强制添加一个
String[] parts = question.toString().split(" ");
int pos = random.nextInt(parts.length / 2 + 1) * 2;
if (pos >= parts.length) pos = parts.length - 1;
if (random.nextBoolean()) {
parts[pos] = parts[pos] + "²";
} else {
parts[pos] = "√" + parts[pos];
}
question = new StringBuilder(String.join(" ", parts));
hasSpecialOperator = true;
}
h = hasSpecialOperator;
q = question;
}
private boolean hasProperOperatorSpacing(String expression) {
String[] parts = expression.split(" ");
for (int i = 0; i < parts.length - 1; i++) {
// 如果当前部分是平方或开方,下一部分必须是运算符
if ((parts[i].endsWith("²") || parts[i].startsWith("√")) &&
i + 1 < parts.length && !isOperator(parts[i + 1])) {
return false;
}
// 如果当前部分是数字,下一部分不是运算符,也不合理
if (parts[i].matches("\\d+") && i + 1 < parts.length && !isOperator(parts[i + 1])) {
return false;
}
}
return true;
}
private boolean isOperator(String str) {
return str.equals("+") || str.equals("-") || str.equals("×") || str.equals("÷");
}
public String addReasonableParentheses(String expression, int operandCount) {
if (operandCount <= 2 || random.nextDouble() < 0.4) {
return expression;
}
String[] parts = expression.split(" ");
if (parts.length < 5) return expression;
StringBuilder newExpr = new StringBuilder();
int start = random.nextInt(Math.max(1, parts.length / 2 - 1));
int end = start + 1 + random.nextInt(Math.max(1, parts.length / 2 - start - 1));
for (int i = 0; i < parts.length; i++) {
if (i == start * 2 && start * 2 < parts.length - 3) {
newExpr.append("( ");
}
newExpr.append(parts[i]);
if (i == end * 2 && i < parts.length - 2 && end * 2 > start * 2 + 2) {
newExpr.append(" )");
}
if (i < parts.length - 1) {
newExpr.append(" ");
}
}
return newExpr.toString().trim();
}
}

@ -0,0 +1,158 @@
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Login {
private static final String USER_FILE = "users.txt";
private static List<User> users = new ArrayList<>();
public void Main() {
initializeUserFile();
load();
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("\n---------登录系统---------");
System.out.println("请输入用户名和密码(用空格隔开): ");
String input = scanner.nextLine().trim();
if (input.equalsIgnoreCase("q")) {
System.out.println("\n已退出");
break;
}
String[] NandP = input.split(" ");
if (NandP.length != 2) {
System.out.println("请输入正确的用户名和密码!");
continue;
}
String username = NandP[0];
String password = NandP[1];
User user = Prove(username, password);
if (user != null) {
Success(user, scanner);
} else {
System.out.println("请输入正确的用户名和密码!");
}
}
scanner.close();
}
private static void initializeUserFile() {
File file = new File(USER_FILE);
if (!file.exists()) {
try (PrintWriter writer = new PrintWriter(new FileWriter(file))) {
writer.println("张三1 123 primary\r\n"
+ "张三2 123 primary\r\n"
+ "张三3 123 primary\r\n"
+ "李四1 123 junior\r\n"
+ "李四2 123 junior\r\n"
+ "李四3 123 junior\r\n"
+ "王五1 123 senior\r\n"
+ "王五2 123 senior\r\n"
+ "王五3 123 senior");
writer.close();
System.out.println("已创建users.txt");
} catch (IOException e) {
System.out.println("创建用户文件失败: " + e.getMessage());
}
}
}
private static void load() {
users.clear();
try (BufferedReader reader = new BufferedReader(new FileReader(USER_FILE))) {
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (!line.isEmpty()) {
String[] parts = line.split(" ");
if (parts.length == 3) {
users.add(new User(parts[0], parts[1], parts[2]));
}
}
}
reader.close();
System.out.println("Loading...");
} catch (IOException e) {
System.out.println("出错!" + e.getMessage());
}
}
private static User Prove(String username, String password) {
for (User user : users) {
if (user.getUsername().equals(username) && user.getPassword().equals(password)) {
return user;
}
}
return null;
}
private static void Success(User user, Scanner scanner) {
String role = getRole(user.getRole());
System.out.println("\n登录成功\n" + user.getUsername() + " [" + role + "]");
QuestionManager questionManager = new QuestionManager(user.getUsername(), user.getRole());
while (true) {
System.out.println("\n输入 -1 退出登录,输入 q 退出程序,输入\"切换为XX\"切换难度XX为小学、初中、高中");
System.out.println("准备生成[" + questionManager.getCurrentRoleChinese() + "]数学题目请输入生成题目数量10~30:");
String input = scanner.nextLine().trim();
if (input.equals("-1")) {
System.out.println("返回登录界面...");
break;
} else if (input.equalsIgnoreCase("q")) {
System.out.println("\n已退出");
System.exit(0);
} else if (input.startsWith("切换为")) {
Switch(questionManager, input);
} else {
try {
int count = Integer.parseInt(input);
if (count >= 10 && count <= 30) {
questionManager.generateQuestions(count);
} else if (count == -1) {
System.out.println("返回登录界面...");
break;
} else {
System.out.println("题目数量应在10~30之间");
}
} catch (NumberFormatException e) {
System.out.println("请输入有效的数字10~30或指定命令");
}
}
}
}
private static void Switch(QuestionManager questionManager, String input) {
String newRole = input.substring(3).trim();
switch (newRole) {
case "小学":
questionManager.setRole("primary");
System.out.println("已切换为小学难度");
break;
case "初中":
questionManager.setRole("junior");
System.out.println("已切换为初中难度");
break;
case "高中":
questionManager.setRole("senior");
System.out.println("已切换为高中难度");
break;
default:
System.out.println("请输入小学、初中和高中三个选项中的一个");
}
}
private static String getRole(String role) {
switch (role) {
case "primary":
return "小学";
case "junior":
return "初中";
case "senior":
return "高中";
default:
return "未知";
}
}
}

@ -0,0 +1,64 @@
public class PrimaryQuestionGenerator extends AbstractQuestionGenerator {
private static final String[] OPERATORS = {"+", "-", "×", "÷"};
@Override
public String generateQuestion() {
int attempts = 0;
while (attempts < 100) {
attempts++;
int operandCount = random.nextInt(4) + 2; // 2~5个操作数
StringBuilder question = new StringBuilder();
// 生成操作数和运算符
for (int i = 0; i < operandCount; i++) {
question.append(generateNumber());
if (i < operandCount - 1) {
question.append(" ").append(generateOperator(OPERATORS)).append(" ");
}
}
// 随机添加括号
String result = addReasonableParentheses(question.toString(), operandCount);
result = ensureBalancedParentheses(result); // 确保括号平衡
if (isQuestionUnique(result) && isValidParentheses(result) && hasOperator(result)) {
addToGeneratedQuestions(result);
String regex = "(?<!\\s)\\)(?=[^)]*$)";
result = result.replaceAll(regex, " )");
return result;
}
}
return "3 + 5"; // 备用题目
}
private String addReasonableParentheses(String expression, int operandCount) {
if (operandCount <= 2 || random.nextDouble() < 0.3) {
return expression;
}
String[] parts = expression.split(" ");
if (parts.length < 5) return expression;
StringBuilder newExpr = new StringBuilder();
int start = random.nextInt(parts.length / 2);
int end = start + random.nextInt(parts.length / 2 - start + 1) + 1;
end = Math.min(end, parts.length / 2 - 1);
for (int i = 0; i < parts.length; i++) {
if (i == start * 2) {
newExpr.append("( ");
}
newExpr.append(parts[i]);
if (i == end * 2 && i >= start * 2 + 2) {
newExpr.append(" )");
}
if (i < parts.length - 1) {
newExpr.append(" ");
}
}
return newExpr.toString().trim();
}
}

@ -0,0 +1,6 @@
public interface QuestionGenerator {
String generateQuestion();
String normalizeQuestion(String question);
String generateOperator(String[] operators);
boolean isValidParentheses(String expression);
}

@ -0,0 +1,94 @@
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
public class QuestionManager {
private QuestionGenerator generator;
private String currentRole;
private String username;
private static final String QUESTIONS_DIR = "questions";
public QuestionManager(String username, String role) {
this.username = username;
setRole(role);
createQuestionsDirectory();
}
public void setRole(String role) {
this.currentRole = role;
switch (role) {
case "primary":
generator = new PrimaryQuestionGenerator();
break;
case "junior":
generator = new JuniorQuestionGenerator();
break;
case "senior":
generator = new SeniorQuestionGenerator();
break;
}
}
// 创建questions目录
private void createQuestionsDirectory() {
File questionsDir = new File(QUESTIONS_DIR);
if (!questionsDir.exists()) {
questionsDir.mkdir();
}
// 创建用户子目录
File userDir = new File(questionsDir, username);
if (!userDir.exists()) {
userDir.mkdir();
}
}
public void generateQuestions(int count) {
if (count < 10 || count > 30) {
System.out.println("题目数量应在10~30之间");
return;
}
// 使用questions目录下的用户文件夹
File userDir = new File(QUESTIONS_DIR, username);
if (!userDir.exists()) {
userDir.mkdir();
}
// 生成文件名
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
String fileName = sdf.format(new Date()) + ".txt";
File outputFile = new File(userDir, fileName);
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
for (int i = 1; i <= count; i++) {
String question = generator.generateQuestion();
writer.println(i + ". " + question);
if (i < count) {
writer.println(); // 题目之间空一行
}
}
System.out.println("题目已生成到: " + outputFile.getPath());
} catch (IOException e) {
System.out.println("生成题目时出错: " + e.getMessage());
}
}
public String getCurrentRoleChinese() {
switch (currentRole) {
case "primary": return "小学";
case "junior": return "初中";
case "senior": return "高中";
default: return "未知";
}
}
// 获取指定用户的所有题目文件(用于查重功能)
public static File[] getUserQuestionFiles(String username) {
File userDir = new File(QUESTIONS_DIR, username);
if (userDir.exists() && userDir.isDirectory()) {
return userDir.listFiles((dir, name) -> name.endsWith(".txt"));
}
return new File[0];
}
}

@ -0,0 +1,163 @@
public class SeniorQuestionGenerator extends AbstractQuestionGenerator{
private static final String[] OPERATORS = {"+", "-", "×", "÷"};
private static boolean h = false;
private static StringBuilder q;
@Override
public String generateQuestion() {
int attempts = 0;
while (attempts < 100) {
attempts++;
int operandCount = random.nextInt(5) + 1; // 1~5个操作数
StringBuilder question = new StringBuilder();
boolean hasTrigOperator = false;
AddTrigOperator(operandCount, hasTrigOperator, question);
hasTrigOperator = h;
question = q;
ForceAddTrigOperator(hasTrigOperator, question);
hasTrigOperator = h;
question = q;
String result = addReasonableParentheses(question.toString(), operandCount);
result = ensureBalancedParentheses(result);
result = Revise(result);
if (isQuestionUnique(result) && isValidParentheses(result) &&
(hasOperator(result) || hasTrigOperator)) {
addToGeneratedQuestions(result);
String regex = "(?<!\\s)\\)(?=[^)]*$)";
result = result.replaceAll(regex, " )");
return result;
}
}
return "sin 30° + cos 45°"; // 备用题目
}
private String addReasonableParentheses(String expression, int operandCount) {
if (operandCount <= 2 || random.nextDouble() < 0.4) {
return expression;
}
String[] parts = expression.split(" ");
if (parts.length < 5) return expression;
StringBuilder newExpr = new StringBuilder();
int start = random.nextInt(Math.max(1, parts.length / 2 - 1));
int end = start + 1 + random.nextInt(Math.max(1, parts.length / 2 - start - 1));
for (int i = 0; i < parts.length; i++) {
if (i == start * 2 && start * 2 < parts.length - 3) {
newExpr.append("( ");
}
newExpr.append(parts[i]);
if (i == end * 2 && i < parts.length - 2 && end * 2 > start * 2 + 2) {
newExpr.append(" )");
}
if (i < parts.length - 1) {
newExpr.append(" ");
}
}
return newExpr.toString().trim();
}
private String Revise(String expression) {
if(!expression.contains("(")) {
return expression;
}
String[] parts = expression.split(" ");
int count = 0;
while(count < 2) {
count++;
for (int i = 1; i < parts.length - 1; i++) {
if (parts[i].equals("(") && (parts[i+1].equals("+") || parts[i+1].equals("-") || parts[i+1].equals("×") || parts[i+1].equals("÷"))) {
String t = parts[i];
parts[i] = parts[i+1];
parts[i+1] = t;
}
if (parts[i].equals(")") && (parts[i-1].equals("+") || parts[i-1].equals("-") || parts[i-1].equals("×") || parts[i-1].equals("÷")
|| parts[i-1].equals("cos") || parts[i-1].equals("sin") || parts[i-1].equals("tan") || parts[i-1].equals("sincos") || parts[i-1].equals("sintan")
|| parts[i-1].equals("cossin") || parts[i-1].equals("costan") || parts[i-1].equals("tansin") || parts[i-1].equals("tancos"))) {
String t = parts[i];
parts[i] = parts[i-1];
parts[i-1] = t;
}
}
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < parts.length; i++) {
if (!parts[i].isEmpty()) {
result.append(parts[i]).append(" ");
}
}
return result.toString();
}
private void AddTrigOperator(int operandCount, boolean hasTrigOperator, StringBuilder question) {
for (int i = 0; i < operandCount; i++) {
// 决定是否添加三角函数
if (!hasTrigOperator && random.nextDouble() < 0.4) {
String trigOp = generateOperator(new String[]{"sin", "cos", "tan"});
int angle = random.nextInt(101);
// 随机决定是否嵌套三角函数30%概率)
if (random.nextDouble() < 0.3) {
String nestedTrig = generateOperator(new String[]{"sin", "cos", "tan"});
while (nestedTrig.equals(trigOp)) {
nestedTrig = generateOperator(new String[]{"sin", "cos", "tan"});
}
question.append(trigOp).append(nestedTrig).append(" ").append(angle).append("°");
} else {
question.append(trigOp).append(" ").append(angle).append("°");
}
hasTrigOperator = true;
} else {
question.append(generateNumber());
}
if (i < operandCount - 1) {
String operator = generateOperator(OPERATORS);
question.append(" ").append(operator).append(" ");
}
}
h = hasTrigOperator;
q = question;
}
private void ForceAddTrigOperator(boolean hasTrigOperator, StringBuilder question) {
// 如果还没有三角函数,强制添加一个
if (!hasTrigOperator) {
String[] parts = question.toString().split(" ");
int pos = random.nextInt(parts.length / 2 + 1) * 2;
if (pos >= parts.length) pos = parts.length - 1;
String trigOp = generateOperator(new String[]{"sin", "cos", "tan"});
int angle = random.nextInt(101);
// 随机决定是否嵌套
if (random.nextDouble() < 0.3) {
String nestedTrig = generateOperator(new String[]{"sin", "cos", "tan"});
while (nestedTrig.equals(trigOp)) {
nestedTrig = generateOperator(new String[]{"sin", "cos", "tan"});
}
parts[pos] = trigOp + nestedTrig + " " + angle + "°";
} else {
parts[pos] = trigOp + " " + angle + "°";
}
question = new StringBuilder(String.join(" ", parts));
hasTrigOperator = true;
}
h = hasTrigOperator;
q = question;
}
}

@ -0,0 +1,7 @@
public class Start {
public static void main(String[] args) {
Login login = new Login();
login.Main();
}
}

@ -0,0 +1,28 @@
public class User {
private String username;
private String password;
private String role;
public User(String username, String password, String role) {
this.username = username;
this.password = password;
this.role = role;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
public String getRole() {
return role;
}
@Override
public String toString() {
return username + " " + password + " " + role;
}
}

Binary file not shown.
Loading…
Cancel
Save