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.
109 lines
3.8 KiB
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;
|
|
}
|
|
} |