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.
MathSystem2/src/main/java/com/example/mathsystemtogether/ChoiceQuestionGenerator.java

212 lines
7.4 KiB

package com.example.mathsystemtogether;
import java.util.*;
/**
* 选择题生成器
*/
public class ChoiceQuestionGenerator {
private final Random random = new Random();
private final int MAX_OPERAND_VALUE = 50; // 降低数值范围,便于计算
private final int MIN_OPERAND_VALUE = 1;
/**
* 生成指定数量的选择题
*/
public List<Question> generateQuestions(Level level, int count) {
List<Question> questions = new ArrayList<>();
Set<String> usedQuestions = new HashSet<>();
int attempts = 0;
int maxAttempts = count * 100; // 最大尝试次数
while (questions.size() < count && attempts < maxAttempts) {
Question question = generateSingleQuestion(level, questions.size() + 1);
String questionKey = question.getQuestionText();
if (!usedQuestions.contains(questionKey)) {
usedQuestions.add(questionKey);
questions.add(question);
}
attempts++;
}
return questions;
}
/**
* 生成单个选择题
*/
private Question generateSingleQuestion(Level level, int questionNumber) {
switch (level) {
case :
return generatePrimaryQuestion(questionNumber);
case :
return generateJuniorQuestion(questionNumber);
case :
return generateSeniorQuestion(questionNumber);
default:
return generatePrimaryQuestion(questionNumber);
}
}
/**
* 生成小学题目
*/
private Question generatePrimaryQuestion(int questionNumber) {
int a = MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE);
int b = MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE);
String operation = getRandomOperation("+*-");
String questionText = String.format("%d %s %d = ?", a, operation, b);
int correctAnswer = calculate(a, b, operation);
// 生成错误选项
List<Integer> options = generateWrongOptions(correctAnswer);
options.add(correctAnswer);
Collections.shuffle(options);
return new Question(questionText,
String.valueOf(options.get(0)),
String.valueOf(options.get(1)),
String.valueOf(options.get(2)),
String.valueOf(options.get(3)),
String.valueOf(correctAnswer),
questionNumber);
}
/**
* 生成初中题目
*/
private Question generateJuniorQuestion(int questionNumber) {
int a = MIN_OPERAND_VALUE + random.nextInt(MAX_OPERAND_VALUE);
// 50%概率生成平方或开方题目
if (random.nextBoolean()) {
// 平方题目
String questionText = String.format("%d² = ?", a);
int correctAnswer = a * a;
List<Integer> options = generateWrongOptions(correctAnswer);
options.add(correctAnswer);
Collections.shuffle(options);
return new Question(questionText,
String.valueOf(options.get(0)),
String.valueOf(options.get(1)),
String.valueOf(options.get(2)),
String.valueOf(options.get(3)),
String.valueOf(correctAnswer),
questionNumber);
} else {
// 开方题目
int perfectSquare = (int) Math.pow(random.nextInt(10) + 1, 2);
String questionText = String.format("√%d = ?", perfectSquare);
int correctAnswer = (int) Math.sqrt(perfectSquare);
List<Integer> options = generateWrongOptions(correctAnswer);
options.add(correctAnswer);
Collections.shuffle(options);
return new Question(questionText,
String.valueOf(options.get(0)),
String.valueOf(options.get(1)),
String.valueOf(options.get(2)),
String.valueOf(options.get(3)),
String.valueOf(correctAnswer),
questionNumber);
}
}
/**
* 生成高中题目
*/
private Question generateSeniorQuestion(int questionNumber) {
int angle = random.nextInt(360);
String[] functions = {"sin", "cos", "tan"};
String function = functions[random.nextInt(functions.length)];
String questionText = String.format("%s(%d°) = ?", function, angle);
double result = calculateTrigFunction(function, angle);
int correctAnswer = (int) Math.round(result * 100) / 100; // 保留两位小数
List<Integer> options = generateWrongOptions(correctAnswer);
options.add(correctAnswer);
Collections.shuffle(options);
return new Question(questionText,
String.valueOf(options.get(0)),
String.valueOf(options.get(1)),
String.valueOf(options.get(2)),
String.valueOf(options.get(3)),
String.valueOf(correctAnswer),
questionNumber);
}
/**
* 生成错误选项
*/
private List<Integer> generateWrongOptions(int correctAnswer) {
List<Integer> options = new ArrayList<>();
Set<Integer> usedOptions = new HashSet<>();
usedOptions.add(correctAnswer);
while (options.size() < 3) {
int wrongAnswer;
if (correctAnswer == 0) {
wrongAnswer = random.nextInt(20) - 10;
} else {
// 生成接近正确答案的错误选项
int variation = random.nextInt(Math.max(1, Math.abs(correctAnswer) / 2)) + 1;
wrongAnswer = correctAnswer + (random.nextBoolean() ? variation : -variation);
}
if (!usedOptions.contains(wrongAnswer)) {
options.add(wrongAnswer);
usedOptions.add(wrongAnswer);
}
}
return options;
}
/**
* 计算基本运算
*/
private int calculate(int a, int b, String operation) {
switch (operation) {
case "+": return a + b;
case "-": return a - b;
case "*": return a * b;
case "/": return b != 0 ? a / b : 0;
default: return 0;
}
}
/**
* 计算三角函数
*/
private double calculateTrigFunction(String function, int angle) {
double radians = Math.toRadians(angle);
switch (function) {
case "sin": return Math.sin(radians);
case "cos": return Math.cos(radians);
case "tan": return Math.tan(radians);
default: return 0;
}
}
/**
* 获取随机运算符
*/
private String getRandomOperation(String operations) {
int index = random.nextInt(operations.length());
return String.valueOf(operations.charAt(index));
}
/**
* 难度级别枚举
*/
public enum Level {
, ,
}
}