1 #5

Merged
hnu202326010315 merged 2 commits from develop into main 5 months ago

10
.idea/.gitignore vendored

@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Environment-dependent path to Maven home directory
/mavenHomeManager.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GoogleJavaFormatSettings">
<option name="enabled" value="true" />
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/relentless1.iml" filepath="$PROJECT_DIR$/relentless1.iml" />
</modules>
</component>
</project>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -1,151 +1,230 @@
import java.util.Random;
/**
*
*
* <p>
*/
public class ElementaryQuestionStrategy implements QuestionStrategy {
private final Random random = new Random();
private final String[] operators = {"+", "-", "*", "/"};
@Override
public String generateQuestion() {
int operandsCount = random.nextInt(4) + 2; // 操作数 2~5
StringBuilder sb = new StringBuilder();
// 生成运算符序列
String[] chosenOps = generateOperators(operandsCount);
// 随机决定括号
int[] parentheses = decideParentheses(operandsCount, chosenOps);
// 拼接表达式
buildExpression(sb, operandsCount, chosenOps, parentheses);
return sb.toString();
}
/**
*
*
*
* @param operandsCount
* @return -1
*/
private String[] generateOperators(int operandsCount) {
String[] chosenOps = new String[operandsCount - 1];
for (int i = 0; i < operandsCount - 1; i++) {
chosenOps[i] = operators[random.nextInt(operators.length)];
}
return chosenOps;
}
/**
*
* 3
*
* @param operandsCount
* @param chosenOps
* @return [openParenIndex, closeParenIndex]-1
*/
private int[] decideParentheses(int operandsCount, String[] chosenOps) {
int openParenIndex = -1;
int closeParenIndex = -1;
if (operandsCount > 2 && random.nextBoolean()) {
openParenIndex = random.nextInt(operandsCount - 1);
closeParenIndex = random.nextInt(operandsCount - openParenIndex - 1) + openParenIndex + 1;
// 如果括号包裹整个表达式,则不需要括号
if (openParenIndex == 0 && closeParenIndex == operandsCount - 1) {
openParenIndex = -1;
closeParenIndex = -1;
} else {
// 检查括号内的运算符优先级是否相同,如果相同则不需要括号
boolean samePrecedence = checkPrecedenceEquality(chosenOps, openParenIndex, closeParenIndex);
if (samePrecedence) {
openParenIndex = -1;
closeParenIndex = -1;
}
}
}
return new int[]{openParenIndex, closeParenIndex};
}
/**
*
*
*
* @param chosenOps
* @param openParenIndex
* @param closeParenIndex
* @return truefalse
*/
private boolean checkPrecedenceEquality(String[] chosenOps, int openParenIndex, int closeParenIndex) {
int precedence = getPrecedence(chosenOps[openParenIndex]);
for (int i = openParenIndex; i < closeParenIndex; i++) {
if (getPrecedence(chosenOps[i]) != precedence) {
return false;
}
}
return true;
}
/**
*
*
*
* @param sb StringBuilder
* @param operandsCount
* @param chosenOps
* @param parentheses [openParenIndex, closeParenIndex]
*/
private void buildExpression(StringBuilder sb, int operandsCount, String[] chosenOps, int[] parentheses) {
int prevNum = random.nextInt(100) + 1;
int openParenIndex = parentheses[0];
int closeParenIndex = parentheses[1];
// 处理第一个操作数可能的开括号
if (openParenIndex == 0) sb.append("(");
sb.append(prevNum);
// 处理最后一个操作数可能的闭括号
if (closeParenIndex == operandsCount - 1) sb.append(")");
// 构建剩余的操作数和运算符
for (int i = 1; i < operandsCount; i++) {
String op = chosenOps[i - 1];
sb.append(" ").append(op).append(" ");
// 根据运算符生成下一个操作数
int num = generateOperand(op, prevNum);
// 添加括号(如果需要)
if (i == openParenIndex) sb.append("(");
sb.append(num);
if (i == closeParenIndex) sb.append(")");
prevNum = num; // 更新上一个数字,供下一轮计算使用
}
}
/**
*
*
*
* @param op
* @param prevNum
* @return
*/
private int generateOperand(String op, int prevNum) {
int num = random.nextInt(100) + 1; // 默认生成1-100之间的随机数
// 如果是减法运算符,确保不会出现负数结果
if (op.equals("-") && num > prevNum) {
num = random.nextInt(prevNum) + 1; // 保证 num <= prevNum避免负数结果
}
return num;
}
private int getPrecedence(String op) {
if (op.equals("+") || op.equals("-")) return 1;
if (op.equals("*") || op.equals("/")) return 2;
return 0;
private static final String[] OPERATORS = {"+", "-", "*", "/"};
private final Random random = new Random();
@Override
public String generateQuestion() {
int operandsCount = random.nextInt(4) + 2; // 操作数数量2~5
StringBuilder sb = new StringBuilder();
// 生成运算符序列
String[] chosenOps = generateOperators(operandsCount);
// 随机决定括号位置
int[] parentheses = decideParentheses(operandsCount, chosenOps);
// 拼接表达式
buildExpression(sb, operandsCount, chosenOps, parentheses);
return sb.toString();
}
/**
*
*
* @param operandsCount
* @return - 1
*/
private String[] generateOperators(int operandsCount) {
String[] chosenOps = new String[operandsCount - 1];
for (int i = 0; i < operandsCount - 1; i++) {
chosenOps[i] = OPERATORS[random.nextInt(OPERATORS.length)];
}
return chosenOps;
}
/**
*
*
* @param sb StringBuilder
* @param operandsCount
* @param chosenOps
* @param parentheses [openParenIndex, closeParenIndex]
*/
private void buildExpression(
StringBuilder sb, int operandsCount, String[] chosenOps, int[] parentheses) {
int openParenIndex = parentheses[0];
int closeParenIndex = parentheses[1];
// 生成第一个操作数
int prevNum = random.nextInt(100) + 1;
// 如果开括号在第一个操作数之前
if (openParenIndex == 0) {
sb.append("(");
}
sb.append(prevNum);
// 如果闭括号在第一个操作数之后(即只包含第一个操作数)
if (closeParenIndex == 0) {
sb.append(")");
}
for (int i = 1; i < operandsCount; i++) {
String op = chosenOps[i - 1];
sb.append(" ").append(op).append(" ");
int num = generateOperand(op, prevNum);
// 如果开括号在当前操作数之前
if (i == openParenIndex) {
sb.append("(");
}
sb.append(num);
// 如果闭括号在当前操作数之后
if (i == closeParenIndex) {
sb.append(")");
}
prevNum = num;
}
// 确保括号正确闭合(安全措施)
String expression = sb.toString();
int openCount = countChar(expression, '(');
int closeCount = countChar(expression, ')');
// 如果括号不匹配,重新生成表达式
if (openCount != closeCount) {
sb.setLength(0); // 清空 StringBuilder
// 递归调用生成新的表达式(或者去掉所有括号)
buildExpressionWithoutParentheses(sb, operandsCount, chosenOps);
}
}
/**
*
*/
private void buildExpressionWithoutParentheses(
StringBuilder sb, int operandsCount, String[] chosenOps) {
int prevNum = random.nextInt(100) + 1;
sb.append(prevNum);
for (int i = 1; i < operandsCount; i++) {
String op = chosenOps[i - 1];
sb.append(" ").append(op).append(" ");
int num = generateOperand(op, prevNum);
sb.append(num);
prevNum = num;
}
}
/**
*
*
* @param str
* @param ch
* @return
*/
private int countChar(String str, char ch) {
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == ch) {
count++;
}
}
return count;
}
/**
*
*
* @param operandsCount
* @param chosenOps
* @return [openParenIndex, closeParenIndex]
*/
private int[] decideParentheses(int operandsCount, String[] chosenOps) {
if (operandsCount <= 2) {
return new int[] {-1, -1}; // 操作数太少,不需要括号
}
if (!random.nextBoolean()) {
return new int[] {-1, -1}; // 随机决定不加括号
}
// 生成有效的括号位置
int openParenIndex = random.nextInt(operandsCount - 1);
int closeParenIndex =
random.nextInt(operandsCount - openParenIndex - 1) + openParenIndex + 1;
// 确保至少包含 2 个操作数
if (closeParenIndex - openParenIndex < 2) {
closeParenIndex = openParenIndex + 1;
}
// 如果括号包裹整个表达式,则不需要括号
if (openParenIndex == 0 && closeParenIndex == operandsCount - 1) {
return new int[] {-1, -1};
}
// 检查括号内运算符是否同一优先级,如果是则不需要括号
boolean samePrecedence = checkPrecedenceEquality(chosenOps, openParenIndex, closeParenIndex);
if (samePrecedence) {
return new int[] {-1, -1};
}
return new int[] {openParenIndex, closeParenIndex};
}
/**
*
*
* @param chosenOps
* @param openParenIndex
* @param closeParenIndex
* @return true
*/
private boolean checkPrecedenceEquality(
String[] chosenOps, int openParenIndex, int closeParenIndex) {
int precedence = getPrecedence(chosenOps[openParenIndex]);
for (int i = openParenIndex; i < closeParenIndex; i++) {
if (getPrecedence(chosenOps[i]) != precedence) {
return false;
}
}
return true;
}
/**
*
*
* <p>
*
* @param op
* @param prevNum
* @return
*/
private int generateOperand(String op, int prevNum) {
int num = random.nextInt(100) + 1;
if (op.equals("-") && num > prevNum) {
num = random.nextInt(prevNum) + 1;
}
return num;
}
/**
*
*
* @param op
* @return
*/
private int getPrecedence(String op) {
if (op.equals("+") || op.equals("-")) {
return 1;
}
if (op.equals("*") || op.equals("/")) {
return 2;
}
return 0;
}
}

@ -1,64 +1,97 @@
import java.io.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
*
*
*/
public class FileUtils {
// 生成文件名
public static String generateFileName() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
return sdf.format(new Date()) + ".txt";
}
/**
*
*
* @return yyyy-MM-dd-HH-mm-ss.txt
*/
public static String generateFileName() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
return sdf.format(new Date()) + ".txt";
}
// 保存题目到用户文件夹
public static void saveQuestionsToFile(String userId, String fileName, List<MathQuestion> questions) {
File userFolder = new File(userId);
if (!userFolder.exists()) {
userFolder.mkdirs();
}
/**
*
*
* @param userId ID
* @param fileName
* @param questions
*/
public static void saveQuestionsToFile(
String userId, String fileName, List<MathQuestion> questions) {
File userFolder = new File(userId);
if (!userFolder.exists()) {
userFolder.mkdirs();
}
File file = new File(userFolder, fileName);
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
for (MathQuestion question : questions) {
writer.write("题号 " + question.getQuestionNumber() + ": " + question.getQuestionText());
writer.newLine();
writer.newLine();
}
writer.flush();
} catch (IOException e) {
throw new RuntimeException("写文件失败: " + file.getAbsolutePath(), e);
}
File file = new File(userFolder, fileName);
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
for (MathQuestion question : questions) {
writer.write(
"题号 " + question.getQuestionNumber() + ": "
+ question.getQuestionText());
writer.newLine();
writer.newLine();
}
writer.flush();
} catch (IOException e) {
throw new RuntimeException("写文件失败: " + file.getAbsolutePath(), e);
}
}
// 读取用户文件夹下所有 txt 文件中已存在的题目
public static Set<String> loadExistingQuestions(String userId) {
Set<String> existingQuestions = new HashSet<>();
File userFolder = new File(userId);
if (!userFolder.exists() || !userFolder.isDirectory()) return existingQuestions;
/**
* txt
*
* @param userId ID
* @return
*/
public static Set<String> loadExistingQuestions(String userId) {
Set<String> existingQuestions = new HashSet<>();
File userFolder = new File(userId);
if (!userFolder.exists() || !userFolder.isDirectory()) {
return existingQuestions;
}
File[] files = userFolder.listFiles((dir, name) -> name != null && name.endsWith(".txt"));
if (files == null) return existingQuestions;
File[] files = userFolder.listFiles(
(dir, name) -> name != null && name.endsWith(".txt"));
if (files == null) {
return existingQuestions;
}
for (File f : files) {
try (BufferedReader reader = new BufferedReader(new FileReader(f))) {
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.isEmpty()) continue;
if (line.startsWith("题号")) {
int idx = line.indexOf(":");
if (idx != -1 && idx + 1 < line.length()) {
existingQuestions.add(line.substring(idx + 1).trim());
}
}
}
} catch (IOException e) {
e.printStackTrace();
for (File f : files) {
try (BufferedReader reader = new BufferedReader(new FileReader(f))) {
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.isEmpty()) {
continue;
}
if (line.startsWith("题号")) {
int idx = line.indexOf(":");
if (idx != -1 && idx + 1 < line.length()) {
existingQuestions.add(line.substring(idx + 1).trim());
}
}
}
return existingQuestions;
} catch (IOException e) {
e.printStackTrace();
}
}
return existingQuestions;
}
}

@ -1,42 +1,48 @@
import java.util.Random;
/**
*
* <p>
*
*/
public class HighSchoolQuestionStrategy implements QuestionStrategy {
private final Random random = new Random();
private final String[] basicOps = {"+", "-", "*", "/"};
private final String[] trigFuncs = {"sin", "cos", "tan"};
@Override
public String generateQuestion() {
// 随机操作数个数 2-5
int operandsCount = random.nextInt(4) + 2;
StringBuilder sb = new StringBuilder();
boolean hasTrig = false;
for (int i = 0; i < operandsCount; i++) {
int num = random.nextInt(100) + 1;
// 每个操作数有概率加三角函数
if (random.nextBoolean()) {
String func = trigFuncs[random.nextInt(trigFuncs.length)];
sb.append(func).append("(").append(num).append(")");
hasTrig = true;
} else {
sb.append(num);
}
if (i != operandsCount - 1) {
String op = basicOps[random.nextInt(basicOps.length)];
sb.append(" ").append(op).append(" ");
}
}
// 确保至少一个三角函数
if (!hasTrig) {
String func = trigFuncs[random.nextInt(trigFuncs.length)];
int num = random.nextInt(100) + 1;
return func + "(" + num + ") + " + sb.toString();
}
return sb.toString();
private static final String[] BASIC_OPS = {"+", "-", "*", "/"};
private static final String[] TRIG_FUNCS = {"sin", "cos", "tan"};
private final Random random = new Random();
@Override
public String generateQuestion() {
// 随机操作数个数2~5
int operandsCount = random.nextInt(4) + 2;
StringBuilder sb = new StringBuilder();
boolean hasTrig = false;
for (int i = 0; i < operandsCount; i++) {
int num = random.nextInt(100) + 1;
// 每个操作数有概率带三角函数
if (random.nextBoolean()) {
String func = TRIG_FUNCS[random.nextInt(TRIG_FUNCS.length)];
sb.append(func).append("(").append(num).append(")");
hasTrig = true;
} else {
sb.append(num);
}
if (i != operandsCount - 1) {
String op = BASIC_OPS[random.nextInt(BASIC_OPS.length)];
sb.append(" ").append(op).append(" ");
}
}
// 确保至少包含一个三角函数
if (!hasTrig) {
String func = TRIG_FUNCS[random.nextInt(TRIG_FUNCS.length)];
int num = random.nextInt(100) + 1;
return func + "(" + num + ") + " + sb;
}
return sb.toString();
}
}

@ -2,99 +2,121 @@ import java.io.IOException;
import java.util.Scanner;
/**
*
*
*/
public class Main {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
User currentUser = null;
/**
*
*
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
User currentUser = null;
System.out.println("-----------------欢迎来到中小学数学卷子自动生成程序-----------------");
// 登录流程
while (true) {
while (currentUser == null) {
System.out.print("请输入用户名和密码,用空格分隔:");
String username = scanner.next();
String password = scanner.next();
// 登录流程
while (true) {
while (currentUser == null) {
System.out.print("请输入用户名和密码,用空格分隔:");
String username = scanner.next();
String password = scanner.next();
currentUser = User.login(username, password);
currentUser = User.login(username, password);
if (currentUser == null) {
System.out.println("请输入正确的用户名、密码");
} else {
clearScreen(); //登录成功清屏
System.out.println("当前选择为 " + currentUser.getRole() + " 出题");
}
}
if (currentUser == null) {
System.out.println("请输入正确的用户名、密码");
} else {
clearScreen(); // 登录成功清屏
System.out.println("当前选择为 " + currentUser.getRole() + " 出题");
}
}
// 每次登录后初始化当前出题类型(账号默认类型)
String currentRole = currentUser.getRole();
// 每次登录后初始化当前出题类型(账号默认类型)
String currentRole = currentUser.getRole();
// 题目生成流程
while (true) {
System.out.println("准备生成 " + currentRole
+ " 数学题目,请输入生成题目数量(输入-1将退出当前用户重新登录");
// 题目生成流程
while (true) {
System.out.println(
"准备生成 " + currentRole
+ " 数学题目,请输入生成题目数量(输入 -1 将退出当前用户,重新登录):");
String input = scanner.next();
String input = scanner.next();
// 退出登录
if (input.equals("-1")) {
currentUser = null;
clearScreen();
System.out.println("已退出当前用户,重新登录...");
break;
}
// 退出登录
if (input.equals("-1")) {
currentUser = null;
clearScreen();
System.out.println("已退出当前用户,重新登录...");
break;
}
// 检测切换命令
if (input.startsWith("切换为")) {
String newRole = input.substring(3).trim();
if (!newRole.equals("小学") && !newRole.equals("初中") && !newRole.equals("高中")) {
System.out.println("请输入小学、初中和高中三个选项中的一个"+"(当前类型为"+currentRole+")");
continue;
}
currentRole = newRole;
clearScreen();
System.out.println("系统提示:准备生成 " + currentRole + " 数学题目,请输入生成题目数量");
continue;
}
// 检测切换命令
if (input.startsWith("切换为")) {
String newRole = input.substring(3).trim();
if (!newRole.equals("小学")
&& !newRole.equals("初中")
&& !newRole.equals("高中")) {
System.out.println(
"请输入小学、初中和高中三个选项中的一个"
+ " (当前类型为 " + currentRole + ")");
continue;
}
currentRole = newRole;
clearScreen();
System.out.println(
"系统提示:准备生成 " + currentRole + " 数学题目,请输入生成题目数量");
continue;
}
// 输入题目数量
int questionCount;
try {
questionCount = Integer.parseInt(input);
} catch (NumberFormatException e) {
System.out.println("请输入有效的数字或使用“切换为小学/初中/高中”命令"+"(当前类型为"+currentRole+")");
continue;
}
// 输入题目数量
int questionCount;
try {
questionCount = Integer.parseInt(input);
} catch (NumberFormatException e) {
System.out.println(
"请输入有效的数字或使用“切换为小学/初中/高中”命令"
+ " (当前类型为 " + currentRole + ")");
continue;
}
if (questionCount < 10 || questionCount > 30) {
System.out.println("请输入有效的题目数量 (10-30) 或 -1 退出");
continue;
}
if (questionCount < 10 || questionCount > 30) {
System.out.println("请输入有效的题目数量 (10-30) 或 -1 退出");
continue;
}
clearScreen();
clearScreen();
// 把 currentRole 传给 QuestionGenerator
QuestionGenerator generator = new QuestionGenerator(currentUser, currentRole);
generator.generateQuestions(questionCount);
System.out.println("题目已生成并保存!\n");
}
}
// 生成题目
QuestionGenerator generator =
new QuestionGenerator(currentUser, currentRole);
generator.generateQuestions(questionCount);
System.out.println("题目已生成并保存!\n");
}
}
}
/**
*
*/
public static void clearScreen() {
try {
if (System.getProperty("os.name").contains("Windows")) {
new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
} else {
new ProcessBuilder("clear").inheritIO().start().waitFor();
}
} catch (Exception e) {
for (int i = 0; i < 50; i++) {
System.out.println();
}
}
/**
*
*/
public static void clearScreen() {
try {
if (System.getProperty("os.name").contains("Windows")) {
new ProcessBuilder("cmd", "/c", "cls")
.inheritIO()
.start()
.waitFor();
} else {
new ProcessBuilder("clear")
.inheritIO()
.start()
.waitFor();
}
} catch (Exception e) {
for (int i = 0; i < 50; i++) {
System.out.println();
}
}
}
}

@ -1,21 +1,36 @@
/**
*
*
*/
public class MathQuestion {
private int questionNumber;
private String questionText;
private final int questionNumber;
private final String questionText;
// 构造方法
public MathQuestion(int questionNumber, String questionText) {
this.questionNumber = questionNumber;
this.questionText = questionText;
}
/**
*
*
* @param questionNumber
* @param questionText
*/
public MathQuestion(int questionNumber, String questionText) {
this.questionNumber = questionNumber;
this.questionText = questionText;
}
public int getQuestionNumber() {
return questionNumber;
}
/**
*
*
* @return
*/
public int getQuestionNumber() {
return questionNumber;
}
public String getQuestionText() {
return questionText;
}
/**
*
*
* @return
*/
public String getQuestionText() {
return questionText;
}
}

@ -1,47 +1,50 @@
import java.util.Random;
/**
*
*/
public class MiddleSchoolQuestionStrategy implements QuestionStrategy {
private final Random random = new Random();
private final String[] basicOps = {"+", "-", "*", "/"}; // 基本运算符
private final Random random = new Random();
private final String[] basicOps = {"+", "-", "*", "/"};
@Override
public String generateQuestion() {
// 随机操作数个数 2-5
int operandsCount = random.nextInt(4) + 2;
StringBuilder sb = new StringBuilder();
boolean hasSquareOrRoot = false;
@Override
public String generateQuestion() {
// 随机操作数个数 2-5
int operandsCount = random.nextInt(4) + 2;
StringBuilder sb = new StringBuilder();
boolean hasSquareOrRoot = false;
// 生成运算符和操作数
for (int i = 0; i < operandsCount; i++) {
int num = random.nextInt(100) + 1; // 生成1-100之间的数字
// 生成运算符和操作数
for (int i = 0; i < operandsCount; i++) {
int num = random.nextInt(100) + 1; // 生成 1-100 之间的数字
// 每个操作数有概率平方或开根号
if (random.nextBoolean()) {
if (random.nextBoolean()) {
sb.append("(").append(num).append(")^2");
hasSquareOrRoot = true; // 标记是否已经使用了平方或根号
} else {
// 确保根号下的数为正
int rootNumber = random.nextInt(100) + 1; // 始终生成正整数
sb.append("√(").append(rootNumber).append(")");
hasSquareOrRoot = true; // 标记是否已经使用了平方或根号
}
} else {
sb.append(num); // 普通数字
}
// 添加运算符(除最后一个操作数外)
if (i != operandsCount - 1) {
String op = basicOps[random.nextInt(basicOps.length)];
sb.append(" ").append(op).append(" ");
}
}
// 如果没有平方或根号,强制添加一个
if (!hasSquareOrRoot) {
// 确保根号下的数为正
int rootNumber = random.nextInt(100) + 1; // 始终生成正整数
sb.append(" + √(").append(rootNumber).append(")");
// 每个操作数有概率平方或开根号。
if (random.nextBoolean()) {
if (random.nextBoolean()) {
sb.append("(").append(num).append(")^2");
hasSquareOrRoot = true;
} else {
// 确保根号下的数为正。
int rootNumber = random.nextInt(100) + 1;
sb.append("√(").append(rootNumber).append(")");
hasSquareOrRoot = true;
}
return sb.toString();
} else {
sb.append(num);
}
// 添加运算符(除最后一个操作数外)。
if (i != operandsCount - 1) {
String op = basicOps[random.nextInt(basicOps.length)];
sb.append(" ").append(op).append(" ");
}
}
// 如果没有平方或根号,强制添加一个。
if (!hasSquareOrRoot) {
int rootNumber = random.nextInt(100) + 1;
sb.append(" + √(").append(rootNumber).append(")");
}
return sb.toString();
}
}

@ -1,51 +1,74 @@
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
*
* 使
*/
public class QuestionGenerator {
private User user;
private String role;
private static final int MAX_TRY_MULTIPLIER = 100;
public QuestionGenerator(User user, String role) {
this.user = user;
this.role = role;
}
/** 当前用户对象。 */
private final User user;
/** 当前用户角色(小学/初中/高中)。 */
private final String role;
/**
*
*
* @param user
* @param role
*/
public QuestionGenerator(User user, String role) {
this.user = user;
this.role = role;
}
/**
*
*
* @param questionCount
* @throws IOException
*/
public void generateQuestions(int questionCount) throws IOException {
// 获取策略
QuestionStrategy strategy = QuestionStrategyFactory.getStrategy(role);
public void generateQuestions(int questionCount) throws IOException {
// 获取策略
QuestionStrategy strategy = QuestionStrategyFactory.getStrategy(role);
// 读出该用户所有历史题目
Set<String> existingQuestions = FileUtils.loadExistingQuestions(user.getUsername());
Set<String> newQuestionsSet = new HashSet<>();
List<MathQuestion> questions = new ArrayList<>();
System.out.println("以下为生成的题目列表:\n");
int i = 1;
int tryCount = 0;
while (questions.size() < questionCount) {
String questionText = strategy.generateQuestion();
tryCount++;
if (existingQuestions.contains(questionText) || newQuestionsSet.contains(questionText)) {
// 如果题库太小可能死循环,这里设置最大尝试次数
if (tryCount > questionCount * 100) {
System.out.println("题库不足,无法生成足够不重复的题目");
break;
}
continue;
}
newQuestionsSet.add(questionText);
MathQuestion question = new MathQuestion(i, questionText);
questions.add(question);
System.out.println("题号 " + i + "" + questionText + "\n");
i++;
// 读取该用户所有历史题目
Set<String> existingQuestions =
FileUtils.loadExistingQuestions(user.getUsername());
Set<String> newQuestionsSet = new HashSet<>();
List<MathQuestion> questions = new ArrayList<>();
System.out.println("以下为生成的题目列表:\n");
int i = 1;
int tryCount = 0;
while (questions.size() < questionCount) {
String questionText = strategy.generateQuestion();
tryCount++;
//这里是为了进行题目的查重
if (existingQuestions.contains(questionText)
|| newQuestionsSet.contains(questionText)) {
// 如果题库太小可能死循环,这里设置最大尝试次数
if (tryCount > questionCount * MAX_TRY_MULTIPLIER) {
System.out.println("题库不足,无法生成足够不重复的题目");
break;
}
continue;
}
String fileName = FileUtils.generateFileName();
FileUtils.saveQuestionsToFile(user.getUsername(), fileName, questions);
newQuestionsSet.add(questionText);
MathQuestion question = new MathQuestion(i, questionText);
questions.add(question);
System.out.println("题号 " + i + "" + questionText + "\n");
i++;
}
String fileName = FileUtils.generateFileName();
FileUtils.saveQuestionsToFile(user.getUsername(), fileName, questions);
}
}

@ -1,26 +0,0 @@
import java.util.HashSet;
import java.util.Set;
/**
*
*/
public class QuestionRepository {
private Set<String> generatedQuestions = new HashSet<>();
/**
*
* @param question
* @return
*/
public boolean isDuplicate(String question) {
return generatedQuestions.contains(question);
}
/**
*
* @param question
*/
public void addQuestion(String question) {
generatedQuestions.add(question);
}
}

@ -1,6 +1,12 @@
/**
*
*
*/
public interface QuestionStrategy {
String generateQuestion();
/**
*
*
* @return
*/
String generateQuestion();
}

@ -1,17 +1,25 @@
/**
* role
*
*/
public class QuestionStrategyFactory {
public static QuestionStrategy getStrategy(String role) {
switch (role) {
case "小学":
return new ElementaryQuestionStrategy();
case "初中":
return new MiddleSchoolQuestionStrategy();
case "高中":
return new HighSchoolQuestionStrategy();
default:
throw new IllegalArgumentException("未知的角色: " + role);
}
/**
*
*
* @param role
* @return
* @throws IllegalArgumentException
*/
public static QuestionStrategy getStrategy(String role) {
switch (role) {
case "小学":
return new ElementaryQuestionStrategy();
case "初中":
return new MiddleSchoolQuestionStrategy();
case "高中":
return new HighSchoolQuestionStrategy();
default:
throw new IllegalArgumentException("未知的角色: " + role);
}
}
}

@ -1,52 +1,67 @@
/**
*
*
*/
public class User {
private String username;
private String password;
private String role;
private final String username;
private final String password;
private final String role;
// 构造方法
public User(String username, String password, String role) {
this.username = username;
this.password = password;
this.role = role;
}
/**
*
*
* @param username
* @param password
* @param role
*/
public User(String username, String password, String role) {
this.username = username;
this.password = password;
this.role = role;
}
/**
*
* @param username
* @param password
* @return null
*/
public static User login(String username, String password) {
String[][] users = {
{"张三1", "123", "小学"}, {"张三2", "123", "小学"}, {"张三3", "123", "小学"},
{"李四1", "123", "初中"}, {"李四2", "123", "初中"}, {"李四3", "123", "初中"},
{"王五1", "123", "高中"}, {"王五2", "123", "高中"}, {"王五3", "123", "高中"}
};
/**
*
*
* @param username
* @param password
* @return {@code null}
*/
public static User login(String username, String password) {
String[][] users = {
{"张三1", "123", "小学"},
{"张三2", "123", "小学"},
{"张三3", "123", "小学"},
{"李四1", "123", "初中"},
{"李四2", "123", "初中"},
{"李四3", "123", "初中"},
{"王五1", "123", "高中"},
{"王五2", "123", "高中"},
{"王五3", "123", "高中"}
};
for (String[] user : users) {
if (user[0].equals(username) && user[1].equals(password)) {
return new User(username, password, user[2]);
}
}
return null;
for (String[] user : users) {
if (user[0].equals(username) && user[1].equals(password)) {
return new User(username, password, user[2]);
}
}
return null;
}
/**
*
* @return
*/
public String getRole() {
return this.role;
}
/**
*
*
* @return
*/
public String getRole() {
return this.role;
}
/**
*
* @return
*/
public String getUsername() {
return this.username;
}
/**
*
*
* @return
*/
public String getUsername() {
return this.username;
}
}

Loading…
Cancel
Save