Compare commits

..

3 Commits

26
.gitignore vendored

@ -1,29 +1,3 @@
# 编译后的类文件
*.class
# 打包文件
*.jar
*.war
*.ear
# IDE 文件
/.idea/
/.settings/
/*.iml
/*.ipr
/*.iws
# 构建工具目录
/target/
/build/
/out/
# 日志文件
*.log
# 系统文件
.DS_Store
Thumbs.db0
### IntelliJ IDEA ### ### IntelliJ IDEA ###
out/ out/
!**/src/main/**/out/ !**/src/main/**/out/

@ -0,0 +1,10 @@
<component name="ArtifactManager">
<artifact type="jar" build-on-make="true" name="MathLearningSoftware:jar">
<output-path>$PROJECT_DIR$/out/artifacts/MathLearningSoftware_jar</output-path>
<root id="archive" name="MathLearningSoftware.jar">
<element id="module-output" name="MathLearningSoftware" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/com/sun/mail/javax.mail/1.6.2/javax.mail-1.6.2.jar" path-in-jar="/" />
<element id="extracted-dir" path="$MAVEN_REPOSITORY$/javax/activation/activation/1.1/activation-1.1.jar" path-in-jar="/" />
</root>
</artifact>
</component>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

@ -25,7 +25,7 @@
## 系统要求 ## 系统要求
- Java 8 或更高版本 - JDK24 或更高版本
- 支持Java Swing的桌面环境 - 支持Java Swing的桌面环境
- 至少 100MB 可用磁盘空间 - 至少 100MB 可用磁盘空间
@ -33,6 +33,7 @@
- 发送验证码邮件的邮箱账号为```3602474328@qq.com``` - 发送验证码邮件的邮箱账号为```3602474328@qq.com```
- 包含验证码的邮件可能会被归类为垃圾邮件,若迟迟未收到验证码请到垃圾箱中翻找一下 - 包含验证码的邮件可能会被归类为垃圾邮件,若迟迟未收到验证码请到垃圾箱中翻找一下
- 用户名和密码都不能出现字符```|```,否则判定为非法 - 用户名和密码都不能出现字符```|```,否则判定为非法
- 登录时使用的是邮箱+密码登录,不是用户名+密码
## 安装和运行 ## 安装和运行

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: com.mathlearning.Main

@ -28,9 +28,7 @@ public abstract class AbstractQuestionGenerator implements QuestionGenerator {
do { do {
question = generateQuestion(level, index); question = generateQuestion(level, index);
attempt++; attempt++;
} while (question != null } while (question != null && questionTexts.contains(question.getQuestionText()) && attempt < 10);
&& questionTexts.contains(question.getQuestionText())
&& attempt < 10);
if (question != null) { if (question != null) {
questionTexts.add(question.getQuestionText()); questionTexts.add(question.getQuestionText());

@ -25,18 +25,10 @@ public abstract class BaseQuestionGenerator {
protected void appendOperator(StringBuilder sb, int operation) { protected void appendOperator(StringBuilder sb, int operation) {
switch (operation) { switch (operation) {
case 0: case 0: sb.append(" + "); break;
sb.append(" + "); case 1: sb.append(" - "); break;
break; case 2: sb.append(" × "); break;
case 1: case 3: sb.append(" ÷ "); break;
sb.append(" - ");
break;
case 2:
sb.append(" × ");
break;
case 3:
sb.append(" ÷ ");
break;
} }
} }
@ -44,6 +36,7 @@ public abstract class BaseQuestionGenerator {
return !(answer < 0 || Double.isNaN(answer) || Double.isInfinite(answer)); return !(answer < 0 || Double.isNaN(answer) || Double.isInfinite(answer));
} }
// 修改使用double进行精确计算只在最后保留小数
protected double calculateExpression(double[] values, int[] operations) { protected double calculateExpression(double[] values, int[] operations) {
List<Double> numbers = new ArrayList<>(); List<Double> numbers = new ArrayList<>();
List<Integer> ops = new ArrayList<>(); List<Integer> ops = new ArrayList<>();
@ -102,22 +95,20 @@ public abstract class BaseQuestionGenerator {
result = performOperation(result, nextNum, op); result = performOperation(result, nextNum, op);
} }
// 修改只在最后一步进行四舍五入保留2位小数
return Math.round(result * 100) / 100.0; return Math.round(result * 100) / 100.0;
} }
private double performOperation(double left, double right, int operation) { private double performOperation(double left, double right, int operation) {
switch (operation) { switch (operation) {
case 0: case 0: return left + right;
return left + right; case 1: return left - right;
case 1: case 2: return left * right;
return left - right;
case 2:
return left * right;
case 3: case 3:
if (right == 0) return Double.NaN; if (right == 0) return Double.NaN;
// 修改:直接进行除法,不在这里保留小数
return left / right; return left / right;
default: default: return left;
return left;
} }
} }
@ -125,8 +116,9 @@ public abstract class BaseQuestionGenerator {
String[] options = new String[4]; String[] options = new String[4];
Set<String> usedValues = new HashSet<>(); Set<String> usedValues = new HashSet<>();
boolean isIntegerAnswer = (answer == (int) answer); // 修改:判断是否为整数的逻辑
String correctAnswer = formatAnswer(answer); boolean isIntegerAnswer = Math.abs(answer - Math.round(answer)) < 1e-10;
String correctAnswer = formatAnswer(answer, isIntegerAnswer);
options[0] = correctAnswer; options[0] = correctAnswer;
usedValues.add(correctAnswer); usedValues.add(correctAnswer);
@ -138,15 +130,16 @@ public abstract class BaseQuestionGenerator {
return new Question(questionText, options, correctIndex, level); return new Question(questionText, options, correctIndex, level);
} }
private void generateWrongOptions( private void generateWrongOptions(String[] options, Set<String> usedValues,
String[] options, Set<String> usedValues, double answer, boolean isIntegerAnswer) { double answer, boolean isIntegerAnswer) {
for (int i = 1; i < 4; i++) { for (int i = 1; i < 4; i++) {
String wrongAnswer; String wrongAnswer;
int attempts = 0; int attempts = 0;
do { do {
double wrongValue = generateWrongValue(answer, isIntegerAnswer); double wrongValue = generateWrongValue(answer, isIntegerAnswer);
wrongAnswer = formatAnswer(wrongValue); wrongAnswer = formatAnswer(wrongValue,
Math.abs(wrongValue - Math.round(wrongValue)) < 1e-10);
attempts++; attempts++;
} while (usedValues.contains(wrongAnswer) && attempts < 20); } while (usedValues.contains(wrongAnswer) && attempts < 20);
@ -159,19 +152,26 @@ public abstract class BaseQuestionGenerator {
double offset = (random.nextDouble() * 5) + 1; double offset = (random.nextDouble() * 5) + 1;
if (isIntegerAnswer) { if (isIntegerAnswer) {
int intAnswer = (int) answer; int intAnswer = (int) Math.round(answer);
int intOffset = random.nextInt(10) + 1; int intOffset = random.nextInt(10) + 1;
double wrongValue = double wrongValue = random.nextBoolean() ?
random.nextBoolean() ? intAnswer + intOffset : Math.max(1, intAnswer - intOffset); intAnswer + intOffset : Math.max(1, intAnswer - intOffset);
return (int) wrongValue; return wrongValue;
} else { } else {
double wrongValue = random.nextBoolean() ? answer + offset : answer - offset; double wrongValue = random.nextBoolean() ? answer + offset : answer - offset;
// 修改错误选项也保留2位小数
return Math.round(wrongValue * 100) / 100.0; return Math.round(wrongValue * 100) / 100.0;
} }
} }
private String formatAnswer(double answer) { // 修改:格式化答案,只在最后一步处理小数位数
return (answer == (int) answer) ? String.valueOf((int) answer) : String.format("%.2f", answer); private String formatAnswer(double answer, boolean isInteger) {
if (isInteger) {
return String.valueOf((int) Math.round(answer));
} else {
// 确保显示2位小数即使末尾是0
return String.format("%.2f", answer);
}
} }
private void shuffleArray(String[] array) { private void shuffleArray(String[] array) {

@ -45,15 +45,14 @@ public class HighSchoolQuestionGenerator extends BaseQuestionGenerator {
private void generateOperandsWithTrig(int[] operands, boolean[] hasTrigOp) { private void generateOperandsWithTrig(int[] operands, boolean[] hasTrigOp) {
for (int i = 0; i < operands.length; i++) { for (int i = 0; i < operands.length; i++) {
operands[i] = operands[i] = hasTrigOp[i] ?
hasTrigOp[i] SPECIAL_ANGLES[random.nextInt(SPECIAL_ANGLES.length)] :
? SPECIAL_ANGLES[random.nextInt(SPECIAL_ANGLES.length)] random.nextInt(100) + 1;
: random.nextInt(100) + 1;
} }
} }
private String buildQuestionText( private String buildQuestionText(int[] operands, int[] operations,
int[] operands, int[] operations, boolean[] hasTrigOp, int[] trigFunctions) { boolean[] hasTrigOp, int[] trigFunctions) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (int i = 0; i < operands.length; i++) { for (int i = 0; i < operands.length; i++) {
@ -72,20 +71,14 @@ public class HighSchoolQuestionGenerator extends BaseQuestionGenerator {
private void appendTrigFunction(StringBuilder sb, int operand, int trigFunction) { private void appendTrigFunction(StringBuilder sb, int operand, int trigFunction) {
switch (trigFunction) { switch (trigFunction) {
case 0: case 0: sb.append("sin(").append(operand).append("°)"); break;
sb.append("sin(").append(operand).append("°)"); case 1: sb.append("cos(").append(operand).append("°)"); break;
break; case 2: sb.append("tan(").append(operand).append("°)"); break;
case 1:
sb.append("cos(").append(operand).append("°)");
break;
case 2:
sb.append("tan(").append(operand).append("°)");
break;
} }
} }
private double calculateAnswer( private double calculateAnswer(int[] operands, int[] operations,
int[] operands, int[] operations, boolean[] hasTrigOp, int[] trigFunctions) { boolean[] hasTrigOp, int[] trigFunctions) {
double[] processedValues = processTrigOperations(operands, hasTrigOp, trigFunctions); double[] processedValues = processTrigOperations(operands, hasTrigOp, trigFunctions);
return calculateExpression(processedValues, operations); return calculateExpression(processedValues, operations);
} }
@ -108,15 +101,12 @@ public class HighSchoolQuestionGenerator extends BaseQuestionGenerator {
double radians = Math.toRadians(angle); double radians = Math.toRadians(angle);
switch (trigFunction) { switch (trigFunction) {
case 0: case 0: return Math.sin(radians);
return Math.sin(radians); case 1: return Math.cos(radians);
case 1:
return Math.cos(radians);
case 2: case 2:
if (angle % 180 == 90 && angle % 360 != 270) return Double.NaN; if (angle % 180 == 90 && angle % 360 != 270) return Double.NaN;
return Math.tan(radians); return Math.tan(radians);
default: default: return 0;
return 0;
} }
} }
} }

@ -27,8 +27,7 @@ public class MiddleSchoolQuestionGenerator extends BaseQuestionGenerator {
return generateOptions(questionText, answer, "初中"); return generateOptions(questionText, answer, "初中");
} }
private void ensureSpecialOperation( private void ensureSpecialOperation(boolean[] hasSpecialOp, int[] specialOpTypes, int operandCount) {
boolean[] hasSpecialOp, int[] specialOpTypes, int operandCount) {
boolean hasSpecialOperation = false; boolean hasSpecialOperation = false;
for (int i = 0; i < operandCount; i++) { for (int i = 0; i < operandCount; i++) {
@ -43,8 +42,8 @@ public class MiddleSchoolQuestionGenerator extends BaseQuestionGenerator {
} }
} }
private String buildQuestionText( private String buildQuestionText(int[] operands, int[] operations,
int[] operands, int[] operations, boolean[] hasSpecialOp, int[] specialOpTypes) { boolean[] hasSpecialOp, int[] specialOpTypes) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (int i = 0; i < operands.length; i++) { for (int i = 0; i < operands.length; i++) {
@ -69,20 +68,19 @@ public class MiddleSchoolQuestionGenerator extends BaseQuestionGenerator {
} }
} }
private double calculateAnswer( private double calculateAnswer(int[] operands, int[] operations,
int[] operands, int[] operations, boolean[] hasSpecialOp, int[] specialOpTypes) { boolean[] hasSpecialOp, int[] specialOpTypes) {
double[] processedValues = processSpecialOperations(operands, hasSpecialOp, specialOpTypes); double[] processedValues = processSpecialOperations(operands, hasSpecialOp, specialOpTypes);
return calculateExpression(processedValues, operations); return calculateExpression(processedValues, operations);
} }
private double[] processSpecialOperations( private double[] processSpecialOperations(int[] operands, boolean[] hasSpecialOp, int[] specialOpTypes) {
int[] operands, boolean[] hasSpecialOp, int[] specialOpTypes) {
double[] processedValues = new double[operands.length]; double[] processedValues = new double[operands.length];
for (int i = 0; i < operands.length; i++) { for (int i = 0; i < operands.length; i++) {
if (hasSpecialOp[i]) { if (hasSpecialOp[i]) {
processedValues[i] = processedValues[i] = (specialOpTypes[i] == 0) ?
(specialOpTypes[i] == 0) ? operands[i] * operands[i] : Math.sqrt(operands[i]); operands[i] * operands[i] : Math.sqrt(operands[i]);
} else { } else {
processedValues[i] = operands[i]; processedValues[i] = operands[i];
} }

@ -21,10 +21,10 @@ public class PrimaryQuestionGenerator extends BaseQuestionGenerator {
boolean useParentheses = random.nextDouble() < 0.3 && operandCount >= 3; boolean useParentheses = random.nextDouble() < 0.3 && operandCount >= 3;
int[] parenthesesPositions = findParenthesesPositions(operations, useParentheses); int[] parenthesesPositions = findParenthesesPositions(operations, useParentheses);
questionText = questionText = buildQuestionText(operands, operations,
buildQuestionText(operands, operations, parenthesesPositions[0], parenthesesPositions[1]); parenthesesPositions[0], parenthesesPositions[1]);
answer = answer = calculateAnswer(operands, operations,
calculateAnswer(operands, operations, parenthesesPositions[0], parenthesesPositions[1]); parenthesesPositions[0], parenthesesPositions[1]);
} while (!isValidAnswer(answer)); } while (!isValidAnswer(answer));
@ -45,7 +45,7 @@ public class PrimaryQuestionGenerator extends BaseQuestionGenerator {
} }
} }
return new int[] {parenStart, parenEnd}; return new int[]{parenStart, parenEnd};
} }
private int findSuitableParenthesesPosition(int[] operations) { private int findSuitableParenthesesPosition(int[] operations) {
@ -86,12 +86,12 @@ public class PrimaryQuestionGenerator extends BaseQuestionGenerator {
return calculateWithParentheses(operands, operations, parenStart, parenEnd); return calculateWithParentheses(operands, operations, parenStart, parenEnd);
} }
private double calculateWithParentheses( private double calculateWithParentheses(int[] operands, int[] operations, int parenStart, int parenEnd) {
int[] operands, int[] operations, int parenStart, int parenEnd) { // 修改使用Double列表
List<Integer> numbers = new ArrayList<>(); List<Double> numbers = new ArrayList<>();
List<Integer> ops = new ArrayList<>(); List<Integer> ops = new ArrayList<>();
for (int operand : operands) numbers.add(operand); for (int operand : operands) numbers.add((double) operand);
for (int operation : operations) ops.add(operation); for (int operation : operations) ops.add(operation);
double parenthesesResult = calculateParenthesesContent(numbers, ops, parenStart, parenEnd); double parenthesesResult = calculateParenthesesContent(numbers, ops, parenStart, parenEnd);
@ -99,28 +99,45 @@ public class PrimaryQuestionGenerator extends BaseQuestionGenerator {
if (!isValidAnswer(parenthesesResult)) return -1; if (!isValidAnswer(parenthesesResult)) return -1;
replaceWithParenthesesResult(numbers, ops, parenStart, parenEnd, parenthesesResult); replaceWithParenthesesResult(numbers, ops, parenStart, parenEnd, parenthesesResult);
return calculateWithoutParentheses(numbers, ops); // 修改:调用新的方法名
return calculateDoubleList(numbers, ops);
} }
private double calculateParenthesesContent( private double calculateParenthesesContent(List<Double> numbers, List<Integer> ops, int start, int end) {
List<Integer> numbers, List<Integer> ops, int start, int end) { List<Double> parenNumbers = new ArrayList<>();
List<Integer> parenNumbers = new ArrayList<>();
List<Integer> parenOps = new ArrayList<>(); List<Integer> parenOps = new ArrayList<>();
for (int i = start; i <= end; i++) parenNumbers.add(numbers.get(i)); for (int i = start; i <= end; i++) parenNumbers.add(numbers.get(i));
for (int i = start; i < end; i++) parenOps.add(ops.get(i)); for (int i = start; i < end; i++) parenOps.add(ops.get(i));
return calculateWithoutParentheses(parenNumbers, parenOps); // 修改:调用新的方法名
return calculateDoubleList(parenNumbers, parenOps);
} }
private void replaceWithParenthesesResult( private void replaceWithParenthesesResult(List<Double> numbers, List<Integer> ops,
List<Integer> numbers, List<Integer> ops, int start, int end, double result) { int start, int end, double result) {
int numCountToRemove = end - start + 1; int numCountToRemove = end - start + 1;
int opCountToRemove = end - start; int opCountToRemove = end - start;
for (int i = 0; i < numCountToRemove; i++) numbers.remove(start); for (int i = 0; i < numCountToRemove; i++) numbers.remove(start);
for (int i = 0; i < opCountToRemove; i++) ops.remove(start); for (int i = 0; i < opCountToRemove; i++) ops.remove(start);
numbers.add(start, (int) Math.round(result)); // 修改直接添加double结果不转换为int
numbers.add(start, result);
}
// 修改:重命名方法,避免与父类冲突
private double calculateDoubleList(List<Double> numbers, List<Integer> ops) {
double[] doubleNumbers = new double[numbers.size()];
for (int i = 0; i < numbers.size(); i++) {
doubleNumbers[i] = numbers.get(i);
}
int[] intOps = new int[ops.size()];
for (int i = 0; i < ops.size(); i++) {
intOps[i] = ops.get(i);
}
return calculateExpression(doubleNumbers, intOps);
} }
} }

@ -1,7 +1,7 @@
package com.mathlearning.model; package com.mathlearning.model;
public class User { public class User {
private String user_name; private String user_name; // 从第一个版本保留
private String email; private String email;
private String password; private String password;
private String registrationCode; private String registrationCode;
@ -12,6 +12,7 @@ public class User {
this.registrationCode = registrationCode; this.registrationCode = registrationCode;
this.isRegistered = false; this.isRegistered = false;
this.password = null; this.password = null;
this.user_name = null; // 添加初始化
} }
// Getters and setters // Getters and setters
@ -19,6 +20,11 @@ public class User {
return email; return email;
} }
public void setEmail(String email) {
this.email = email;
}
// user_name 相关方法(从第一个版本保留)
public String getUser_name() { public String getUser_name() {
return user_name; return user_name;
} }
@ -27,10 +33,6 @@ public class User {
this.user_name = user_name; this.user_name = user_name;
} }
public void setEmail(String email) {
this.email = email;
}
public String getPassword() { public String getPassword() {
return password; return password;
} }

Loading…
Cancel
Save