From 287b6c78559d82177ccb6dd2eb32f3e87407898e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E6=99=A8=E6=97=AD?= <15550449+ruantang231@user.noreply.gitee.com> Date: Sat, 11 Oct 2025 17:07:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=AB=98=E4=B8=AD=E5=87=BA?= =?UTF-8?q?=E9=A2=98=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ChoiceQuestionGenerator.java | 300 ++++++++++++++---- user_data.txt | 2 + 2 files changed, 233 insertions(+), 69 deletions(-) create mode 100644 user_data.txt diff --git a/src/main/java/com/example/mathsystemtogether/ChoiceQuestionGenerator.java b/src/main/java/com/example/mathsystemtogether/ChoiceQuestionGenerator.java index 6fce20b..9638bad 100644 --- a/src/main/java/com/example/mathsystemtogether/ChoiceQuestionGenerator.java +++ b/src/main/java/com/example/mathsystemtogether/ChoiceQuestionGenerator.java @@ -9,31 +9,31 @@ 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 generateQuestions(Level level, int count) { List questions = new ArrayList<>(); Set 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; } - + /** * 生成单个选择题 */ @@ -49,38 +49,38 @@ public class ChoiceQuestionGenerator { 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 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), + + 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()) { // 平方题目 @@ -89,13 +89,13 @@ public class ChoiceQuestionGenerator { List 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), + + 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 { // 开方题目 @@ -105,42 +105,216 @@ public class ChoiceQuestionGenerator { List 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), + + 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); + // 使用常见角度: 0°, 30°, 45°, 60°, 90°, 120°, 135°, 150°, 180°, 210°, 225°, 270°, 300°, 315°, 330° + int[] commonAngles = {0, 30, 45, 60, 90, 120, 135, 150, 180, 210, 225, 270, 300, 315, 330}; + int angle = commonAngles[random.nextInt(commonAngles.length)]; 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 options = generateWrongOptions(correctAnswer); - options.add(correctAnswer); + + // 生成选项 + List options = generateTrigOptions(result); + // 使用格式化后的值作为正确答案,确保与选项一致 + String correctAnswer = formatTrigValue(result); + + // 随机打乱选项 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); + + return new Question(questionText, + options.get(0), + options.get(1), + options.get(2), + options.get(3), + correctAnswer, + questionNumber); +} + +/** + * 生成三角函数题目的选项 + */ +private List generateTrigOptions(double correctAnswer) { + List options = new ArrayList<>(); + Set usedOptions = new HashSet<>(); + + // 格式化正确答案,保留适当的小数位数 + String formattedCorrectAnswer = formatTrigValue(correctAnswer); + options.add(formattedCorrectAnswer); + usedOptions.add(formattedCorrectAnswer); + + // 添加常见三角函数值作为错误选项 + String[] commonValues = {"0", "0.5", "0.71", "0.87", "1", "1.73", "-0.5", "-0.71", "-0.87", "-1", "-1.73", "undefined"}; + List commonValuesList = new ArrayList<>(Arrays.asList(commonValues)); + + // 打乱常见值列表 + Collections.shuffle(commonValuesList); + + // 添加错误选项 + int wrongOptionsNeeded = 3; + for (String value : commonValuesList) { + if (wrongOptionsNeeded <= 0) break; + // 确保不添加与正确答案相同的选项 + if (!usedOptions.contains(value) && !value.equals(formattedCorrectAnswer)) { + options.add(value); + usedOptions.add(value); + wrongOptionsNeeded--; + } + } + + // 如果还需要更多选项,则生成接近正确答案的选项 + while (options.size() < 4) { + String wrongOption = generateNearbyValue(correctAnswer, usedOptions); + // 确保新生成的选项不重复且不与正确答案相同 + if (!usedOptions.contains(wrongOption) && !wrongOption.equals(formattedCorrectAnswer)) { + options.add(wrongOption); + usedOptions.add(wrongOption); + } + } + + return options; +} + +/** + * 格式化三角函数值 + */ +private String formatTrigValue(double value) { + // 对于特殊值进行精确表示 + if (Math.abs(value) < 1e-10) return "0"; // 接近0的值 + if (Math.abs(value - 1.0) < 1e-10) return "1"; + if (Math.abs(value + 1.0) < 1e-10) return "-1"; + if (Math.abs(value - 0.5) < 1e-10) return "0.5"; + if (Math.abs(value + 0.5) < 1e-10) return "-0.5"; + if (Math.abs(value - Math.sqrt(2)/2) < 1e-10) return "0.71"; // √2/2 ≈ 0.707 + if (Math.abs(value + Math.sqrt(2)/2) < 1e-10) return "-0.71"; + if (Math.abs(value - Math.sqrt(3)/2) < 1e-10) return "0.87"; // √3/2 ≈ 0.866 + if (Math.abs(value + Math.sqrt(3)/2) < 1e-10) return "-0.87"; + if (Math.abs(value - Math.sqrt(3)) < 1e-10) return "1.73"; // √3 ≈ 1.732 + if (Math.abs(value + Math.sqrt(3)) < 1e-10) return "-1.73"; + + // 对于tan(90°)等未定义值 + if (Double.isInfinite(value) || Double.isNaN(value)) { + return "undefined"; + } + + // 其他值保留两位小数 + return String.format("%.2f", value); +} + +/** + * 生成接近正确答案的选项 + */ +private String generateNearbyValue(double correctAnswer, Set usedOptions) { + // 对于特殊值直接返回简单值 + if (Double.isInfinite(correctAnswer) || Double.isNaN(correctAnswer)) { + return "0"; + } + + // 生成在正确答案附近的值 + double variation = (random.nextDouble() - 0.5) * 2; // -1 到 1 之间的随机数 + double wrongAnswer = correctAnswer + variation; + + // 格式化生成的值 + String formatted = formatTrigValue(wrongAnswer); + + // 确保不会生成与已使用选项相同的值,最多尝试10次 + int attempts = 0; + while (usedOptions.contains(formatted) && attempts < 10) { + variation = (random.nextDouble() - 0.5) * 2; + wrongAnswer = correctAnswer + variation; + formatted = formatTrigValue(wrongAnswer); + attempts++; + } + + return formatted; +} + +/** + * 计算三角函数 + */ +private double calculateTrigFunction(String function, int angle) { + double radians = Math.toRadians(angle); + switch (function) { + case "sin": + // 对特定角度返回精确值 + switch (angle) { + case 0: return 0; + case 30: return 0.5; + case 45: return Math.sqrt(2)/2; + case 60: return Math.sqrt(3)/2; + case 90: return 1; + case 120: return Math.sqrt(3)/2; + case 135: return Math.sqrt(2)/2; + case 150: return 0.5; + case 180: return 0; + case 210: return -0.5; + case 225: return -Math.sqrt(2)/2; + case 270: return -1; + case 300: return -Math.sqrt(3)/2; + case 315: return -Math.sqrt(2)/2; + case 330: return -0.5; + default: return Math.sin(radians); + } + case "cos": + // 对特定角度返回精确值 + switch (angle) { + case 0: return 1; + case 30: return Math.sqrt(3)/2; + case 45: return Math.sqrt(2)/2; + case 60: return 0.5; + case 90: return 0; + case 120: return -0.5; + case 135: return -Math.sqrt(2)/2; + case 150: return -Math.sqrt(3)/2; + case 180: return -1; + case 210: return -Math.sqrt(3)/2; + case 225: return -Math.sqrt(2)/2; + case 270: return 0; + case 300: return 0.5; + case 315: return Math.sqrt(2)/2; + case 330: return Math.sqrt(3)/2; + default: return Math.cos(radians); + } + case "tan": + // 对特定角度返回精确值或未定义 + switch (angle) { + case 0: return 0; + case 30: return Math.sqrt(3)/3; + case 45: return 1; + case 60: return Math.sqrt(3); + case 90: return Double.POSITIVE_INFINITY; // 未定义 + case 120: return -Math.sqrt(3); + case 135: return -1; + case 150: return -Math.sqrt(3)/3; + case 180: return 0; + case 210: return Math.sqrt(3)/3; + case 225: return 1; + case 270: return Double.POSITIVE_INFINITY; // 未定义 + case 300: return -Math.sqrt(3); + case 315: return -1; + case 330: return -Math.sqrt(3)/3; + default: return Math.tan(radians); + } + default: return 0; } - +} + + /** * 生成错误选项 */ @@ -148,7 +322,7 @@ public class ChoiceQuestionGenerator { List options = new ArrayList<>(); Set usedOptions = new HashSet<>(); usedOptions.add(correctAnswer); - + while (options.size() < 3) { int wrongAnswer; if (correctAnswer == 0) { @@ -158,16 +332,16 @@ public class ChoiceQuestionGenerator { 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; } - + /** * 计算基本运算 */ @@ -180,20 +354,8 @@ public class ChoiceQuestionGenerator { 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; - } - } - + + /** * 获取随机运算符 */ @@ -201,7 +363,7 @@ public class ChoiceQuestionGenerator { int index = random.nextInt(operations.length()); return String.valueOf(operations.charAt(index)); } - + /** * 难度级别枚举 */ diff --git a/user_data.txt b/user_data.txt new file mode 100644 index 0000000..cc12efd --- /dev/null +++ b/user_data.txt @@ -0,0 +1,2 @@ +wgll|123456|ymhlovesLQX@163.com|小学|1760162416490 +666|123456789|252436951@qq.com|小学|1760166999971