You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
partner_project/src/service/ExamService.java

109 lines
3.8 KiB

package service;
import auth.User;
import generator.Problem;
import generator.ProblemGenerator;
import generator.PrimaryGenerator;
import generator.MiddleGenerator;
import generator.HighGenerator;
import util.FileUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class ExamService {
public ProblemGenerator getGenerator(String type) {
switch (type) {
case "小学": return new PrimaryGenerator();
case "初中": return new MiddleGenerator();
case "高中": return new HighGenerator();
default: return null;
}
}
private Problem generateUniqueProblem(ProblemGenerator generator,
Set<String> historyExpressions) {
int attempts = 0;
final int maxAttemptsPerProblem = 1000;
while (attempts < maxAttemptsPerProblem) {
Problem problem = generator.generateProblems(1).get(0);
// 查重基于题干 (表达式字符串)
if (!historyExpressions.contains(problem.getExpression())) {
historyExpressions.add(problem.getExpression());
return problem;
}
attempts++;
}
return null;
}
// R5: 生成一张唯一试卷,并将其保存到用户的历史记录中。
public List<Problem> generateExam(User currentUser, int count) {
if (count < 10 || count > 30) {
throw new IllegalArgumentException("题目数量必须在 10 到 30 之间");
}
ProblemGenerator generator = getGenerator(currentUser.getType());
if (generator == null) {
System.err.println("错误: 无法获取题目生成器,用户类型: " + currentUser.getType());
return new ArrayList<>();
}
Set<String> historyExpressions = FileUtils.loadHistory(currentUser.getUsername());
List<Problem> problems = new ArrayList<>();
for(int i = 0; i < count; i++) {
Problem problem = generateUniqueProblem(generator, historyExpressions);
if (problem != null) {
problems.add(problem);
} else {
System.err.println("警告: 无法生成足够数量的唯一题目。已生成: " + problems.size() + " 题");
break;
}
}
if (!problems.isEmpty()) {
FileUtils.saveProblems(currentUser.getUsername(), problems);
} else {
System.err.println("错误: 未能生成任何题目");
}
return problems;
}
// 将这个私有方法改为公共方法,以便在其他类中调用
public boolean isAnswerCorrect(Problem problem, String userAnswer) {
if (userAnswer == null || problem.getCorrectAnswerOption() == null) {
return false;
}
boolean isCorrect = userAnswer.trim().equalsIgnoreCase(problem.getCorrectAnswerOption().trim());
return isCorrect;
}
// R6: 根据答对的百分比计算分数。
public int calculateScore(List<Problem> problems, List<String> answers) {
if (problems == null || answers == null ||
problems.size() != answers.size() ||
problems.isEmpty()) {
System.err.println("评分错误: 题目和答案数量不匹配");
return 0;
}
int correctCount = 0;
for (int i = 0; i < problems.size(); i++) {
Problem problem = problems.get(i);
String userAnswer = answers.get(i);
if (isAnswerCorrect(problem, userAnswer)) {
correctCount++;
}
}
double score = ((double) correctCount / problems.size()) * 100;
int finalScore = (int) Math.round(score);
return finalScore;
}
}