final2 功能完全实现,未加注释

pull/1/head
杨博文 5 months ago
parent c01b8ffc71
commit 34c2af894e

@ -1,9 +1,11 @@
package mathpuzzle;
import mathpuzzle.controller.StartController;
public class Main {
public static void main(String[] args) {
StartController startController = new StartController();
startController.start();
}
public static void main(String[] args) {
StartController startController = new StartController();
startController.start();
}
}

@ -1,96 +1,133 @@
package mathpuzzle.controller;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import mathpuzzle.entity.User;
import mathpuzzle.service.*;
import mathpuzzle.service.FileHandler;
import mathpuzzle.service.JuniorHighGenerator;
import mathpuzzle.service.PrimarySchoolGenerator;
import mathpuzzle.service.QuestionDeduplicator;
import mathpuzzle.service.QuestionGenerator;
import mathpuzzle.service.SeniorHighGenerator;
import mathpuzzle.system.LogSystem;
public class StartController {
private LogSystem logSystem = new LogSystem();
private QuestionDeduplicator deduplicator = new QuestionDeduplicator();
private FileHandler fileHandler = new FileHandler();
//private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
public void start() {
logSystem.userHashMapInit();
Scanner scanner = new Scanner(System.in);
while (true) {
User user = logSystem.login();
if (user == null) {
continue;
}
while (true) {
System.out.println("准备生成 " + user.getLevel() + "数学题目,请输入生成题目数量(输入-1将退出当前用户重新登录");
String input = scanner.nextLine();
try {
if ("-1".equals(input)) {
System.out.println("退出当前用户");
break;
}
int count = Integer.parseInt(input);
if (count < 10 || count > 30) {
System.out.println("题目数量必须在10-30之间");
continue;
}
handleQuestionGeneration(user, count);
} catch (NumberFormatException e) {
handleLevelSwitch(user, input);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private LogSystem logSystem = new LogSystem();
private QuestionDeduplicator deduplicator = new QuestionDeduplicator();
private FileHandler fileHandler = new FileHandler();
public void start() {
logSystem.userHashMapInit();
Scanner scanner = new Scanner(System.in);
while (true) {
User user = logSystem.login();
if (user == null) {
continue;
}
while (true) {
System.out.println("准备生成" + user.getLevel()
+ "数学题目,请输入生成题目数量(输入-1将退出当前用户重新登录");
String input = scanner.nextLine();
try {
if ("-1".equals(input)) {
System.out.println("退出当前用户");
break;
}
int count = Integer.parseInt(input);
if (count < 10 || count > 30) {
System.out.println("题目数量必须在10-30之间");
continue;
}
handleQuestionGeneration(user, count);
} catch (NumberFormatException e) {
handleLevelSwitch(user, input);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
private void handleLevelSwitch(User user, String input) {
if (input.startsWith("切换为")) {
String newLevel = input.substring(3);
if ("小学".equals(newLevel) || "初中".equals(newLevel) || "高中".equals(newLevel)) {
user.setLevel(newLevel);
} else {
System.out.println("请输入小学、初中和高中三个选项中的一个");
}
} else {
System.out.println("无效输入。请输入题目数量或'切换为 XX'指令。");
}
}
private void handleLevelSwitch(User user, String input) {
if (input.startsWith("切换为")) {
String newLevel = input.substring(3);
if ("小学".equals(newLevel) || "初中".equals(newLevel) || "高中".equals(newLevel)) {
user.setLevel(newLevel);
} else {
System.out.println("请输入小学、初中和高中三个选项中的一个");
}
} else {
System.out.println("无效输入。请输入题目数量或'切换为 XX'指令。");
}
private void handleQuestionGeneration(User user, int count) throws IOException {
// 根据用户级别创建生成器
QuestionGenerator generator = createGenerator(user.getLevel());
if (generator == null) {
System.out.println("不支持的题目类型: " + user.getLevel());
return;
}
}
private QuestionGenerator createGenerator(String level) {
switch (level) {
case "小学":
return new PrimarySchoolGenerator();
case "初中":
return new JuniorHighGenerator();
case "高中":
return new SeniorHighGenerator();
default:
return null;
}
}
// 加载历史题目用于查重
deduplicator.loadExistingQuestions(user);
// 处理题目生成,进行去重工作
private void handleQuestionGeneration(User user, int count) throws IOException {
QuestionGenerator generator = createGenerator(user.getLevel());
if (generator == null) {
System.out.println("不支持的题目类型: " + user.getLevel());
return;
}
// 生成题目
List<String> questions = generator.generateQuestions(count);
// 加载该用户所有历史题目用于查重
deduplicator.loadExistingQuestions(user);
// 显示题目
for (int i = 0; i < questions.size(); i++) {
System.out.println((i + 1) + ". " + questions.get(i));
}
List<String> finalQuestions = new ArrayList<>();
int generatedCount = 0;
int maxAttempts = 1000; // 防止因题目空间耗尽而无限循环
int attempts = 0;
while (generatedCount < count && attempts < maxAttempts) {
attempts++;
// 临时生成一个题目列表(这里可以优化为一次生成一个)
List<String> tempQuestions = generator.generateQuestions(1);
if (tempQuestions.isEmpty()) {
continue;
}
String newQuestion = tempQuestions.get(0);
// 移除末尾的 " =" 以便查重更准确(可选,取决于你如何存储历史题)
String questionForDedup = newQuestion.endsWith(" =") ?
newQuestion.substring(0, newQuestion.length() - 2) : newQuestion;
// 保存到文件
fileHandler.savePaper(user, questions);
System.out.println("试卷已成功保存!");
if (!deduplicator.isDuplicate(questionForDedup)) {
// 题目不重复,加入最终列表和查重集
finalQuestions.add(newQuestion);
deduplicator.addQuestion(questionForDedup); // 加入本次会话的查重集,防止本次生成重复
generatedCount++;
//System.out.println("生成一道题目");
}
// 如果重复,则丢弃,循环继续
}
private QuestionGenerator createGenerator(String level) {
switch (level) {
case "小学":
return new PrimarySchoolGenerator();
case "初中":
return new JuniorHighGenerator();
case "高中":
return new SeniorHighGenerator();
default:
return null;
}
if (generatedCount < count) {
System.out.println(
"警告:在尝试了 " + maxAttempts + " 次后,仅生成了 " + generatedCount + " 道不重复的题目。");
}
// 显示并保存题目
for (int i = 0; i < finalQuestions.size(); i++) {
System.out.println((i + 1) + ". " + finalQuestions.get(i));
}
fileHandler.savePaper(user, finalQuestions);
System.out.println("试卷已成功保存!");
}
}

@ -1,24 +1,30 @@
package mathpuzzle.entity;
public class User {
private String name;
private String password;
private String level;
public User(String name, String password, String level) {
this.name = name;
this.password = password;
this.level = level;
}
public String getName() {
return name;
}
public String getPassword() {
return password;
}
public String getLevel() {
return level;
}
public void setLevel(String newLevel) {
level = newLevel;
}
private final String name;
private final String password;
private String level;
public User(String name, String password, String level) {
this.name = name;
this.password = password;
this.level = level;
}
public String getName() {
return name;
}
public String getPassword() {
return password;
}
public String getLevel() {
return level;
}
public void setLevel(String newLevel) {
level = newLevel;
}
}

@ -0,0 +1,67 @@
package mathpuzzle.service;
import static mathpuzzle.service.PrimarySchoolGenerator.isNumeric;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
public class CaculatePrimary {
private final Stack<Double> numStack = new Stack<>();
private final Stack<String> opStack = new Stack<>();
private final Map<String, Integer> precedence = new HashMap<>();
public double caculate(List<String> expression) {
precedence.put("+", 1);
precedence.put("-", 1);
precedence.put("*", 2);
precedence.put("/", 2);
for (String opOrNum : expression) {
if (isNumeric(opOrNum)) {
numStack.push(Double.parseDouble(opOrNum));
} else if (opOrNum.equals("(")) {
opStack.push(opOrNum);
} else if (opOrNum.equals(")")) {
while (!opStack.peek().equals("(") && !opStack.isEmpty()) {
doCaculte();
}
opStack.pop();
} else if (precedence.containsKey(opOrNum)) {
while (!opStack.isEmpty() && !opStack.peek().equals("(")
&& precedence.get(opOrNum) <= precedence.get(opStack.peek())) {
doCaculte();
}
opStack.push(opOrNum);
}
}
while (!opStack.isEmpty()) {
doCaculte();
}
return numStack.pop();
}
public void doCaculte() {
String op = opStack.pop();
double num2 = numStack.pop();
double num1 = numStack.pop();
switch (op) {
case "+":
numStack.push(num1 + num2);
break;
case "-":
numStack.push(num1 - num2);
break;
case "*":
numStack.push(num1 * num2);
break;
case "/":
numStack.push(num1 / num2);
break;
default:
break;
}
}
}

@ -1,4 +1,5 @@
package mathpuzzle.service;
import mathpuzzle.entity.User;
import java.io.BufferedWriter;
import java.io.FileWriter;
@ -11,32 +12,31 @@ import java.time.format.DateTimeFormatter;
import java.util.List;
/**
*
*
*
*/
public class FileHandler {
public void ensureUserDirectory(User user) throws IOException {
String dirPath = "./" + user.getName();
Path path = Paths.get(dirPath);
if (!Files.exists(path)) {
Files.createDirectories(path);
}
public void ensureUserDirectory(User user) throws IOException {
String dirPath = "./" + user.getName();
Path path = Paths.get(dirPath);
if (!Files.exists(path)) {
Files.createDirectories(path);
}
}
public void savePaper(User user, List<String> questions) throws IOException {
ensureUserDirectory(user);
// 生成文件名:年-月-日-时-分-秒.txt
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss");
String fileName = LocalDateTime.now().format(formatter) + ".txt";
String filePath = "./" + user.getName() + "/" + fileName;
public void savePaper(User user, List<String> questions) throws IOException {
ensureUserDirectory(user);
// 生成文件名:年-月-日-时-分-秒.txt
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss");
String fileName = LocalDateTime.now().format(formatter) + ".txt";
String filePath = "./" + user.getName() + "/" + fileName;
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
for (int i = 0; i < questions.size(); i++) {
writer.write((i + 1) + ". " + questions.get(i)); // 添加题号
writer.newLine();
writer.newLine(); // 每题之间空一行
}
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
for (int i = 0; i < questions.size(); i++) {
writer.write((i + 1) + ". " + questions.get(i)); // 添加题号
writer.newLine();
writer.newLine(); // 每题之间空一行
}
}
}
}

@ -1,122 +1,127 @@
package mathpuzzle.service;
import java.util.*;
import static mathpuzzle.service.PrimarySchoolGenerator.isNumeric;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
*
*
*
*/
public class JuniorHighGenerator implements QuestionGenerator {
private static final String[] ADVANCED_OPS = {"平方", "开根号"};
private static final String[] OPERATORS = {"+", "-", "*", "/"};
private final Random random = new Random();
@Override
public List<String> generateQuestions(int count) {
List<String> questions = new ArrayList<>();
for (int i = 0; i < count; i++) {
String question = generateSingleQuestion();
questions.add(question);
}
return questions;
private static final String[] ADVANCED_OPS = {"平方", "开根号"};
private static final String[] OPERATORS = {"+", "-", "*", "/"};
private final Random random = new Random();
@Override
public List<String> generateQuestions(int count) {
List<String> questions = new ArrayList<>();
for (int i = 0; i < count; i++) {
String question = generateSingleQuestion();
questions.add(question);
}
return questions;
}
private String generateSingleQuestion() {
List<String> parts = new ArrayList<>();
int operandCount = random.nextInt(5) + 1;
parts = generateBase(operandCount, parts);
// hasAdvancedOp用以检测下面的循环是否加入了高级运算符如果没有就启动保底
boolean hasAdvancedOp = false;
if (operandCount == 1) {
if ("平方".equals(ADVANCED_OPS[random.nextInt(ADVANCED_OPS.length)])) {
parts.add("平方");
} else {
parts.set(0, "开根号" + parts.get(0));
}
hasAdvancedOp = true;
} else {
// 遍历查找左括号的合理位置
for(int i = 0; i < parts.size() - 2; i++) {
// 该位置要为操作数且随机添加括号
if (isNumeric(parts.get(i)) && random.nextBoolean()) {
// 随机数看取出来的是不是开根号运算符
if("开根号".equals(ADVANCED_OPS[random.nextInt(ADVANCED_OPS.length)])) {
parts = generateRoot(parts, i);
}
// 如果不是开根号就是平方运算
else {
parts = generateSquare(parts, i);
}
hasAdvancedOp = true;
break;
}
}
private String generateSingleQuestion() {
List<String> parts = new ArrayList<>();
int operandCount = random.nextInt(5) + 1;
parts = generateBase(operandCount, parts);
// hasAdvancedOp用以检测下面的循环是否加入了高级运算符如果没有就启动保底
boolean hasAdvancedOp = false;
if (operandCount == 1) {
if ("平方".equals(ADVANCED_OPS[random.nextInt(ADVANCED_OPS.length)])) {
parts.add("平方");
} else {
parts.set(0, "开根号" + parts.get(0));
}
hasAdvancedOp = true;
} else {
// 遍历查找左括号的合理位置
for (int i = 0; i < parts.size() - 2; i++) {
// 该位置要为操作数且随机添加括号
if (isNumeric(parts.get(i)) && random.nextBoolean()) {
// 随机数看取出来的是不是开根号运算符
if ("开根号".equals(ADVANCED_OPS[random.nextInt(ADVANCED_OPS.length)])) {
parts = generateRoot(parts, i);
}
// 如果不是开根号就是平方运算
else {
parts = generateSquare(parts, i);
}
hasAdvancedOp = true;
break;
}
// 启动保底强制加入一个高级运算符
if(!hasAdvancedOp) {
parts = forceAddAdvancedOp(parts);
}
return String.join(" ", parts) + " =";
}
}
// 产生基本操作
public List<String> generateBase(int operandCount, List<String> parts) {
for (int i = 0; i < operandCount; i++) {
int num = random.nextInt(100) + 1;
parts.add(String.valueOf(num));
if (i < operandCount - 1) {
parts.add(OPERATORS[random.nextInt(OPERATORS.length)]);
}
}
return parts;
// 启动保底强制加入一个高级运算符
if (!hasAdvancedOp) {
parts = forceAddAdvancedOp(parts);
}
// 强制加入一个高级运算符
public List<String> forceAddAdvancedOp(List<String> parts) {
String advancedOp = ADVANCED_OPS[random.nextInt(ADVANCED_OPS.length)];
if ("平方".equals(advancedOp)) {
parts.add("平方");
} else { // 开根号
parts.set(0, "开根号(" + parts.get(0));
parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")" );
}
return parts;
return String.join(" ", parts) + " =";
}
// 产生基本操作
public List<String> generateBase(int operandCount, List<String> parts) {
for (int i = 0; i < operandCount; i++) {
int num = random.nextInt(100) + 1;
parts.add(String.valueOf(num));
if (i < operandCount - 1) {
parts.add(OPERATORS[random.nextInt(OPERATORS.length)]);
}
}
return parts;
}
// 强制加入一个高级运算符
public List<String> forceAddAdvancedOp(List<String> parts) {
String advancedOp = ADVANCED_OPS[random.nextInt(ADVANCED_OPS.length)];
if ("平方".equals(advancedOp)) {
parts.add("平方");
} else { // 开根号
parts.set(0, "开根号(" + parts.get(0));
parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")");
}
return parts;
}
public List<String> generateRoot(List<String> parts, int i) {
if(random.nextBoolean()) {
parts.set(i, "开根号(" + parts.get(i) + ")");
} else {
parts.set(i, "开根号(" + parts.get(i));
// 为避免随机数上限出现0此处要单独判断一下左括号正好括住倒数第二个操作数的情况
if (i == parts.size() - 3) {
parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")");
} else {
while(true) {
int i2 = random.nextInt(parts.size() - 3 - i) + 2;
if(isNumeric(parts.get(i + i2))) {
parts.set(i + i2, parts.get(i + i2) + ")");
break;
}
}
}
public List<String> generateRoot(List<String> parts, int i) {
if (random.nextBoolean()) {
parts.set(i, "开根号(" + parts.get(i) + ")");
} else {
parts.set(i, "开根号(" + parts.get(i));
// 为避免随机数上限出现0此处要单独判断一下左括号正好括住倒数第二个操作数的情况
if (i == parts.size() - 3) {
parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")");
} else {
while (true) {
int i2 = random.nextInt(parts.size() - 3 - i) + 2;
if (isNumeric(parts.get(i + i2))) {
parts.set(i + i2, parts.get(i + i2) + ")");
break;
}
}
return parts;
}
}
return parts;
}
public List<String> generateSquare(List<String> parts, int i) {
parts.set(i, "(" + parts.get(i));
// 为避免随机数上限出现0此处要单独判断一下左括号正好括住倒数第二个操作数的情况
if (i == parts.size() - 3) {
parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")");
} else {
while(true) {
int i2 = random.nextInt(parts.size() - 3 - i) + 2;
if(isNumeric(parts.get(i + i2))) {
parts.set(i + i2, parts.get(i + i2) + ")平方");
break;
}
}
public List<String> generateSquare(List<String> parts, int i) {
parts.set(i, "(" + parts.get(i));
// 为避免随机数上限出现0此处要单独判断一下左括号正好括住倒数第二个操作数的情况
if (i == parts.size() - 3) {
parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")");
} else {
while (true) {
int i2 = random.nextInt(parts.size() - 3 - i) + 2;
if (isNumeric(parts.get(i + i2))) {
parts.set(i + i2, parts.get(i + i2) + ")平方");
break;
}
return parts;
}
}
return parts;
}
}

@ -1,74 +1,88 @@
package mathpuzzle.service;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
*
* +, -, *, / ()
* +, -, *, / ()
*/
public class PrimarySchoolGenerator implements QuestionGenerator {
private static final String[] OPERATORS = {"+", "-", "*", "/"};
private final Random random = new Random();
@Override
public List<String> generateQuestions(int count) {
List<String> questions = new ArrayList<>();
for (int i = 0; i < count; i++) {
String question = generateSingleQuestion();
questions.add(question);
}
return questions;
private static final String[] OPERATORS = {"+", "-", "*", "/"};
private final Random random = new Random();
@Override
public List<String> generateQuestions(int count) {
List<String> questions = new ArrayList<>();
for (int i = 0; i < count; i++) {
String question = generateSingleQuestion();
questions.add(question);
}
private String generateSingleQuestion() {
int operandCount = random.nextInt(4) + 2; // 2-5个操作数
List<String> parts = new ArrayList<>();
// 生成基础操作
parts = generateBase(operandCount, parts);
// 简单添加括号逻辑:随机加一个括号
if (operandCount > 2 && random.nextBoolean()) {
// 遍历查找左括号的合理位置
for(int i = 0; i < parts.size() - 2; i++) {
// 该位置要为操作数且随机添加括号
if (isNumeric(parts.get(i)) && random.nextBoolean()) {
parts.set(i, "(" + parts.get(i));
// 为避免随机数上限出现0此处要单独判断一下左括号正好括住倒数第二个操作数的情况
if (i == parts.size() - 3) {
parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")");
} else {
while(true) {
int i2 = random.nextInt(parts.size() - 3 - i) + 2;
if(isNumeric(parts.get(i + i2))) {
parts.set(i + i2, parts.get(i + i2) + ")");
break;
}
}
}
break;
return questions;
}
private String generateSingleQuestion() {
CaculatePrimary caculatePrimary = new CaculatePrimary();
int operandCount = random.nextInt(4) + 2; // 2-5个操作数
List<String> parts = new ArrayList<>();
while (true) {
// 生成基础操作
parts = generateBase(operandCount, parts);
// 简单添加括号逻辑:随机加一个括号
if (operandCount > 2 && random.nextBoolean()) {
// 遍历查找左括号的合理位置
for (int i = 0; i < parts.size() - 2; i++) {
// 该位置要为操作数且随机添加括号
if (isNumeric(parts.get(i)) && random.nextBoolean()) {
parts.add(i, "(");
i++;
// 为避免随机数上限出现0此处要单独判断一下左括号正好括住倒数第二个操作数的情况
if (i == parts.size() - 3) {
parts.add(")");
} else {
while (true) {
int i2 = random.nextInt(parts.size() - 3 - i) + 2;
if (isNumeric(parts.get(i + i2))) {
parts.add(i + i2 + 1, ")");
break;
}
}
}
break;
}
}
}
if (caculatePrimary.caculate(parts) >= 0) {
return String.join(" ", parts) + " =";
} else {
parts.clear();
}
}
}
public static boolean isNumeric(String str) {
if (str == null || str.isEmpty()) {
return false;
}
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
}
public static boolean isNumeric(String str) {
if (str == null || str.isEmpty()) {
return false;
}
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
public List<String> generateBase(int operandCount, List<String> parts) {
for (int i = 0; i < operandCount; i++) {
int num = random.nextInt(100) + 1;
parts.add(String.valueOf(num));
if (i < operandCount - 1) {
parts.add(OPERATORS[random.nextInt(OPERATORS.length)]);
}
}
return parts;
public List<String> generateBase(int operandCount, List<String> parts) {
for (int i = 0; i < operandCount; i++) {
int num = random.nextInt(100) + 1;
parts.add(String.valueOf(num));
if (i < operandCount - 1) {
parts.add(OPERATORS[random.nextInt(OPERATORS.length)]);
}
}
return parts;
}
}

@ -1,53 +1,57 @@
package mathpuzzle.service;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import mathpuzzle.entity.User;
import java.io.*;
import java.util.HashSet;
import java.util.Set;
/**
*
*
*
*/
public class QuestionDeduplicator {
private Set<String> existingQuestions = new HashSet<>();
public void loadExistingQuestions(User user) {
existingQuestions.clear();
String userDir = "./" + user.getName();
File dir = new File(userDir);
private final Set<String> existingQuestions = new HashSet<>();
if (!dir.exists()) {
return; // 目录不存在,无历史题目
}
public void loadExistingQuestions(User user) {
existingQuestions.clear();
String userDir = "./" + user.getName();
File dir = new File(userDir);
if (!dir.exists()) {
return; // 目录不存在,无历史题目
}
File[] files = dir.listFiles((d, name) -> name.endsWith(".txt"));
if (files == null) return;
for (File file : files) {
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
// 只加载题目行,忽略题号和空行
if (line.trim().isEmpty() || line.matches("\\d+\\. .*")) {
String questionContent = line.replaceFirst("\\d+\\. ", "").trim();
if (!questionContent.isEmpty() && !questionContent.equals("=")) {
existingQuestions.add(questionContent);
}
}
}
} catch (IOException e) {
System.err.println("读取历史文件时出错: " + file.getName());
File[] files = dir.listFiles((d, name) -> name.endsWith(".txt"));
if (files == null) {
return;
}
for (File file : files) {
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
// 只加载题目行,忽略题号和空行
if (line.trim().isEmpty() || line.matches("\\d+\\. .*")) {
String questionContent = line.replaceFirst("\\d+\\. ", "").trim();
if (!questionContent.isEmpty() && !questionContent.equals("=")) {
existingQuestions.add(questionContent);
}
}
}
} catch (IOException e) {
System.err.println("读取历史文件时出错: " + file.getName());
}
}
}
public boolean isDuplicate(String question) {
return existingQuestions.contains(question);
}
public boolean isDuplicate(String question) {
return existingQuestions.contains(question);
}
public void addQuestion(String question) {
existingQuestions.add(question);
}
public void addQuestion(String question) {
existingQuestions.add(question);
}
}

@ -1,6 +1,8 @@
package mathpuzzle.service;
import java.util.List;
public interface QuestionGenerator {
List<String> generateQuestions(int count);
List<String> generateQuestions(int count);
}

@ -1,84 +1,88 @@
package mathpuzzle.service;
import java.util.*;
import static mathpuzzle.service.PrimarySchoolGenerator.isNumeric;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
*
* sin, cos, tan
* sin, cos, tan
*/
public class SeniorHighGenerator implements QuestionGenerator {
private static final String[] TRIG_FUNCS = {"sin", "cos", "tan"};
private static final String[] OPERATORS = {"+", "-", "*", "/"};
private final Random random = new Random();
@Override
public List<String> generateQuestions(int count) {
List<String> questions = new ArrayList<>();
for (int i = 0; i < count; i++) {
String question = generateSingleQuestion();
questions.add(question);
}
return questions;
private static final String[] TRIG_FUNCS = {"sin", "cos", "tan"};
private static final String[] OPERATORS = {"+", "-", "*", "/"};
private final Random random = new Random();
@Override
public List<String> generateQuestions(int count) {
List<String> questions = new ArrayList<>();
for (int i = 0; i < count; i++) {
String question = generateSingleQuestion();
questions.add(question);
}
return questions;
}
private String generateSingleQuestion() {
List<String> parts = new ArrayList<>();
int operandCount = random.nextInt(5) + 1;
parts = generateBase(operandCount, parts);
String advancedOp;
// hasAdvancedOp用以检测下面的循环是否加入了高级运算符如果没有就启动保底
if(operandCount == 1) {
advancedOp = TRIG_FUNCS[random.nextInt(TRIG_FUNCS.length)];
parts.set(0, advancedOp + parts.get(0));
} else {
// 遍历查找左括号的合理位置
for(int i = 0; i < parts.size(); i++) {
// 最后一次循环保底生成高中三角函数
if (i == parts.size()-1) {
advancedOp = TRIG_FUNCS[random.nextInt(TRIG_FUNCS.length)];
parts.set(i, advancedOp + parts.get(i));
} else if (isNumeric(parts.get(i)) && random.nextBoolean()) { // 随机数看是否为操作数且随即进入生成程序
// 进入随机生成tan\sin\cos的程序
parts = generateTrig(parts, i);
break;
}
}
private String generateSingleQuestion() {
List<String> parts = new ArrayList<>();
int operandCount = random.nextInt(5) + 1;
parts = generateBase(operandCount, parts);
String advancedOp;
// hasAdvancedOp用以检测下面的循环是否加入了高级运算符如果没有就启动保底
if (operandCount == 1) {
advancedOp = TRIG_FUNCS[random.nextInt(TRIG_FUNCS.length)];
parts.set(0, advancedOp + parts.get(0));
} else {
// 遍历查找左括号的合理位置
for (int i = 0; i < parts.size(); i++) {
// 最后一次循环保底生成高中三角函数
if (i == parts.size() - 1) {
advancedOp = TRIG_FUNCS[random.nextInt(TRIG_FUNCS.length)];
parts.set(i, advancedOp + parts.get(i));
} else if (isNumeric(parts.get(i)) && random.nextBoolean()) {// 随机数看是否为操作数且随即进入生成程序
// 进入随机生成tan\sin\cos的程序
parts = generateTrig(parts, i);
break;
}
return String.join(" ", parts) + " =";
}
}
// 产生基本操作
public List<String> generateBase(int operandCount, List<String> parts) {
for (int i = 0; i < operandCount; i++) {
int num = random.nextInt(100) + 1;
parts.add(String.valueOf(num));
if (i < operandCount - 1) {
parts.add(OPERATORS[random.nextInt(OPERATORS.length)]);
}
}
return parts;
return String.join(" ", parts) + " =";
}
// 产生基本操作
public List<String> generateBase(int operandCount, List<String> parts) {
for (int i = 0; i < operandCount; i++) {
int num = random.nextInt(100) + 1;
parts.add(String.valueOf(num));
if (i < operandCount - 1) {
parts.add(OPERATORS[random.nextInt(OPERATORS.length)]);
}
}
return parts;
}
// 产生三角函数运算符
public List<String> generateTrig(List<String> parts, int i) {
String trigOp = TRIG_FUNCS[random.nextInt(TRIG_FUNCS.length)];
if(random.nextBoolean()) {
parts.set(i, trigOp + parts.get(i));
} else {
parts.set(i, trigOp + "(" + parts.get(i));
// 为避免随机数上限出现0此处要单独判断一下左括号正好括住倒数第二个操作数的情况
if (i == parts.size() - 3) {
parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")");
} else {
while(true) {
int i2 = random.nextInt(parts.size() - 3 - i) + 2;
if(isNumeric(parts.get(i + i2))) {
parts.set(i + i2, parts.get(i + i2) + ")");
break;
}
}
}
// 产生三角函数运算符
public List<String> generateTrig(List<String> parts, int i) {
String trigOp = TRIG_FUNCS[random.nextInt(TRIG_FUNCS.length)];
if (random.nextBoolean()) {
parts.set(i, trigOp + parts.get(i));
} else {
parts.set(i, trigOp + "(" + parts.get(i));
// 为避免随机数上限出现0此处要单独判断一下左括号正好括住倒数第二个操作数的情况
if (i == parts.size() - 3) {
parts.set(parts.size() - 1, parts.get(parts.size() - 1) + ")");
} else {
while (true) {
int i2 = random.nextInt(parts.size() - 3 - i) + 2;
if (isNumeric(parts.get(i + i2))) {
parts.set(i + i2, parts.get(i + i2) + ")");
break;
}
}
return parts;
}
}
return parts;
}
}

@ -4,7 +4,7 @@ import java.util.HashMap;
import java.util.Scanner;
public class LogSystem {
private HashMap<String, User> userHashMap = new HashMap<String, User>();
private final HashMap<String, User> userHashMap = new HashMap<>();
public void userHashMapInit() {
// 小学
userHashMap.put("张三1", new User("张三 1", "123", "小学"));
@ -27,21 +27,18 @@ public class LogSystem {
String[] info = scanner.nextLine().split(" ");
if(info.length != 2) {
System.out.println("请输入正确格式");
continue;
} else {
String name = info[0];
String password = info[1];
User user = userHashMap.get(name);
if (user == null) {
System.out.println("输入正确的用户名、密码");
continue;
System.out.println("请输入正确的用户名、密码");
}
else if (!user.getPassword().equals(password)) {
System.out.println("输入正确的用户名、密码");
continue;
System.out.println("请输入正确的用户名、密码");
}
else {
System.out.println("登录成功");
System.out.println("当前选择为" + user.getLevel() + "出题");
return user;
}
}

Loading…
Cancel
Save