Violet_branch
Violet 5 months ago
parent 8f80b21da7
commit 30cec4d97d

@ -0,0 +1,19 @@
1. 75 * ( 4 / 10 ) * 39
2. 7 / 64 / 38
3. 55 * 80 / 29
4. 51 - 68 - 71 + ( 73 - 47 )
5. 42 - 23
6. 58 + 40 - ( 2 - 52 )
7. 17 - 24
8. 79 * 41 + ( 11 * 71 ) - 74
9. 10 * ( 1 / 1 )
10. 67 * 76 - 47

@ -0,0 +1,19 @@
1. 33 + 28
2. 78 - 41
3. 93 + 26 - 67
4. 71 - 62 + -13.0 - 62
5. 89 - 41
6. 44 - 3
7. 40 - 38
8. 19 + 91
9. 57 + 63
10. 60 - ( 23 - 1 )

@ -0,0 +1,19 @@
1. 58 + (18 * 5)
2. (98 * 20) / 56
3. 22 - 12
4. 22 - 15
5. 43 - 2
6. 3 * 13
7. 67 - 51
8. 20 * 1
9. 80 * 14
10. 86 + (16 * 2)

@ -0,0 +1,19 @@
1. 72 * pow(2,2)
2. 81 + 5 / pow(73,2) * 99 / 97
3. 46 * 16 - pow(42,2) / 64 / 79
4. 31 + pow(55,2)
5. 17 / 67 / pow(62,2) + 32
6. 67 / 77 / pow(49,2) + 77
7. 95 / pow(74,2)
8. 46 + pow(86,2) - 28
9. 97 + pow(41,2)
10. 29 / pow(12,2) * 2

@ -0,0 +1,19 @@
1. 73 + 24 - pow(10,2) - 70 - 50
2. 25 + pow(68,2)
3. 100 - 74 - pow(14,2) / 26
4. 38 + pow(90,2)
5. 79 / pow(12,2)
6. 59 + 41 / pow(71,2) * 51 - 68
7. 14 - pow(97,2)
8. 19 + pow(82,2) / 92
9. 27 - 47 + pow(84,2) - 53
10. 14 + 34 / pow(64,2) / 60 / 83

@ -0,0 +1,19 @@
1. 51 * pow(84,2)
2. 47 - 55 * pow(58,2) - 58 / 64
3. 42 + pow(78,2) - 50
4. 98 - pow(74,2)
5. 31 + pow(97,2) * 12
6. 27 + 83 + pow(89,2) - 54
7. 42 * pow(22,2) + 7
8. 52 + 28 + pow(43,2) / 98 * 39
9. 24 * pow(22,2) + 57
10. 73 / pow(9,2)

@ -0,0 +1,19 @@
1. 17 * 13 - 180
2. 47 - 16
3. 92 - 52 - 34
4. (97 + 3) - 76
5. 64 - 9
6. (12 - 10) * 3
7. 30 + (9 / 13)
8. (25 - 3) / 2
9. 73 - 37
10. 71 * 6 / 426

@ -0,0 +1,19 @@
1. 36 * 69 - 54
2. 76 * 87 / 97 + 100
3. 55 * 56 * 79
4. (√36) + 46
5. 18 - (√81)
6. 21 / 38 + 91
7. 89 / 85 + 55 + 91
8. 24 * 63 / 32
9. 45 * 53 * 5
10. 95 * 87 * (√64)

@ -0,0 +1,19 @@
1. (√16) * 98
2. 33 / 100 / 28
3. 99 - 57 - 35 - (√16)
4. 17 - (√36) * 87
5. 7 / 57 - 32 * 10
6. 24 - 79
7. 51 - 86 / (√64) - 74
8. 13 * 49 / 95 - 54
9. 53 / 55 * 59 / 97
10. 13 / 47 - 48

@ -0,0 +1,19 @@
1. 87 + (√49) + 69 + 82
2. 27 * 28 - 79 / 50
3. 10 + (√1) * 5
4. 26 * 24
5. 57 - (√36) * 52
6. 67 + 5 / 95
7. 37 + (√9) * 36 + 18
8. 11 / 38 / (√49)
9. 29 * 97
10. 55 + 91 + 85

@ -0,0 +1,19 @@
1. 20 + 65
2. 4 + 28 * 74 * tan(12)
3. 46 - tan(2) / 73 / 56
4. cos(321) - 67
5. 6 + 34 * 87 + tan(83)
6. 26 - 65
7. 51 + 69 - tan(19)
8. 52 / 49 - 78 - 63
9. 60 * 50 * 11
10. cos(232) / 54

@ -0,0 +1,19 @@
1. 32 / 9 / sin(8)
2. tan(57) + 16
3. 45 / 55 * 5 - 31
4. 19 - 48 * 22
5. 26 + 78
6. 38 + 14
7. 39 + cos(22) - 55
8. 90 / 82 + 41
9. 55 * 94 / 83 / 15
10. 91 * sin(241) - 55

@ -0,0 +1,19 @@
1. 80 + tan(0)
2. sin(265) - 39 - 40
3. 52 - cos(229) - 69
4. sin(268) * 82
5. 71 + tan(21)
6. cos(74) + 100
7. 60 * cos(299)
8. cos(325) * 68
9. cos(138) + 96 / 14
10. 48 - 92 / sin(107)

@ -0,0 +1,19 @@
1. 10 + 83 / (√4)
2. (√4) / 47
3. 17 - 54 + (√36)
4. 57 / (√64)
5. 80 / (√100) + 34
6. 50 / (√16) - 44
7. 76 - (√100) / 12
8. 80 - (√64)
9. (√1) - 87 / 37
10. 10 - (√16) - 10

@ -0,0 +1,59 @@
1. 70 + (√64)
2. (√36) - 19
3. 25 + (√25) / 46
4. 71 * (√25)
5. (√25) - 40
6. 47 * 8 + (√9)
7. (√9) / 34
8. 88 - (√49)
9. 3 + (√100) / 94
10. 82 - 5 * (√1)
11. 5 - 18 - (√49)
12. (√81) * 100 * 18
13. (√100) / 8
14. (√16) * 31
15. (√16) * 76
16. 74 + 46 * (√49)
17. (√1) - 75
18. (√25) + 97
19. (√25) - 75
20. 21 / (√9) / 72
21. (√16) * 99
22. (√100) - 45
23. (√1) + 27 * 30
24. 46 * (√64)
25. (√49) - 11
26. (√49) * 80 + 20
27. 18 - 20 - (√1)
28. (√81) / 97
29. (√81) - 53
30. 72 - (√100) - 37

@ -91,18 +91,92 @@ public class QuestionGenerator {
* @return
*/
private String generatePrimaryExpression() {
int termCount = random.nextInt(4) + 2;
StringBuilder expr = new StringBuilder();
int termCount = random.nextInt(2) + 2; // 2或3个操作数
char[] operators = {'+', '-', '*', '/'};
expr.append(random.nextInt(100) + 1);
for (int i = 1; i < termCount; i++) {
char op = operators[random.nextInt(operators.length)];
int num = random.nextInt(100) + 1;
expr.append(" ").append(op).append(" ").append(num);
int num1 = random.nextInt(100) + 1;
char op1 = operators[random.nextInt(operators.length)];
int num2;
// 为第一个操作符生成第二个操作数,并确保合法性
if (op1 == '-') {
num2 = random.nextInt(num1 + 1); // 确保 num1 >= num2
} else if (op1 == '/') {
List<Integer> divisors = getDivisors(num1);
num2 = divisors.get(random.nextInt(divisors.size()));
} else { // + or *
num2 = random.nextInt(20) + 1; // 乘法和加法的数小一点,避免结果过大
}
// 如果只有两个操作数,直接返回
if (termCount == 2) {
return String.format("%d %c %d", num1, op1, num2);
}
// --- 如果有三个操作数 ---
String firstPart = String.format("%d %c %d", num1, op1, num2);
double interimResult;
try {
interimResult = evaluateExpression(firstPart);
} catch (Exception e) {
// 如果第一部分计算出错(理论上不应该),则简化为两项操作
return firstPart;
}
// 确保中间结果为非负整数
if (interimResult < 0 || interimResult != (int)interimResult) {
return firstPart; // 不满足条件,提前返回两项操作
}
char op2 = operators[random.nextInt(operators.length)];
int num3;
// 为第二个操作符生成第三个操作数,并确保合法性
if (op2 == '-') {
num3 = random.nextInt((int) interimResult + 1); // 确保 interimResult >= num3
} else if (op2 == '/') {
if (interimResult == 0) { // 除数不能为0
op2 = '+'; // 将操作符改为加法
num3 = random.nextInt(20) + 1;
} else {
List<Integer> divisors = getDivisors((int)interimResult);
num3 = divisors.get(random.nextInt(divisors.size()));
}
} else { // + or *
num3 = random.nextInt(20) + 1;
}
return addBrackets(expr.toString());
// 随机决定是否以及如何添加括号
if (random.nextBoolean()) {
return String.format("(%d %c %d) %c %d", num1, op1, num2, op2, num3);
} else {
// 检查第二个操作符优先级是否高于第一个
if ((op2 == '*' || op2 == '/') && (op1 == '+' || op1 == '-')) {
return String.format("%d %c (%d %c %d)", num1, op1, num2, op2, num3);
}
// 默认无括号或左侧括号
return String.format("%d %c %d %c %d", num1, op1, num2, op2, num3);
}
}
/**
*
* @param n
* @return
*/
private List<Integer> getDivisors(int n) {
List<Integer> divisors = new ArrayList<>();
if (n == 0) {
divisors.add(1); // 除数不能为0返回1作为安全值
return divisors;
}
n = Math.abs(n); // 处理可能的负数输入
for (int i = 1; i <= n; i++) {
if (n % i == 0) {
divisors.add(i);
}
}
return divisors;
}
/**
@ -141,10 +215,10 @@ public class QuestionGenerator {
* @return
*/
private String generateMiddleExpression() {
int termCount = random.nextInt(4) + 2;
int termCount = random.nextInt(2) + 2; // 2或3个项
StringBuilder expr = new StringBuilder();
char[] operators = {'+', '-', '*', '/'};
boolean hasPowerOrSqrt = false;
int specialOpIndex = random.nextInt(termCount); // 随机决定哪一项是特殊运算
for (int i = 0; i < termCount; i++) {
if (i > 0) {
@ -152,29 +226,22 @@ public class QuestionGenerator {
expr.append(" ").append(op).append(" ");
}
int num = random.nextInt(100) + 1;
if (i == termCount / 2 && !hasPowerOrSqrt) {
if (i == specialOpIndex) {
// 强制生成特殊运算
if (random.nextBoolean()) {
// 生成平方运算
int num = random.nextInt(15) + 1; // 平方的底数小一些
expr.append("pow(").append(num).append(",2)");
} else {
expr.append("sqrt(").append(num).append(")");
// 生成开方运算, 确保是完全平方数
int sqrtNum = random.nextInt(10) + 1; // 1-10
int perfectSquare = sqrtNum * sqrtNum;
expr.append("(√").append(perfectSquare).append(")");
}
hasPowerOrSqrt = true;
} else {
expr.append(num);
}
}
if (!hasPowerOrSqrt) {
int num = random.nextInt(100) + 1;
char op = operators[random.nextInt(operators.length)];
if (random.nextBoolean()) {
expr.append(" ").append(op).append(" pow(").append(num).append(",2)");
} else {
expr.append(" ").append(op).append(" sqrt(").append(num).append(")");
expr.append(random.nextInt(100) + 1);
}
}
return expr.toString();
}
@ -184,11 +251,11 @@ public class QuestionGenerator {
* @return
*/
private String generateHighExpression() {
int termCount = random.nextInt(4) + 2;
int termCount = random.nextInt(2) + 2; // 2或3个项
StringBuilder expr = new StringBuilder();
char[] operators = {'+', '-', '*', '/'};
String[] functions = {"sin", "cos", "tan"};
boolean hasTrig = false;
int trigFuncIndex = random.nextInt(termCount); // 随机决定哪一项是三角函数
for (int i = 0; i < termCount; i++) {
if (i > 0) {
@ -196,24 +263,20 @@ public class QuestionGenerator {
expr.append(" ").append(op).append(" ");
}
if (i == termCount / 2 && !hasTrig) {
if (i == trigFuncIndex) {
// 强制生成三角函数
String func = functions[random.nextInt(functions.length)];
int angle = random.nextInt(100);
int angle;
if ("tan".equals(func)) {
angle = random.nextInt(90); // tan的角度范围 0-89
} else {
angle = random.nextInt(361); // sin/cos的角度范围 0-360
}
expr.append(func).append("(").append(angle).append(")");
hasTrig = true;
} else {
expr.append(random.nextInt(100) + 1);
}
}
if (!hasTrig) {
String func = functions[random.nextInt(functions.length)];
int angle = random.nextInt(100);
char op = operators[random.nextInt(operators.length)];
expr.append(" ").append(op).append(" ");
expr.append(func).append("(").append(angle).append(")");
}
return expr.toString();
}
@ -224,15 +287,17 @@ public class QuestionGenerator {
* @return
*/
private double evaluateExpression(String expression) {
String expr = expression.replace(" ", "");
expr = expr.replaceAll("pow\\((\\d+),2\\)", "($1*$1)");
expr = expr.replaceAll("sqrt\\((\\d+)\\)", "Math.sqrt($1)");
expr = expr.replaceAll("sin\\((\\d+)\\)", "Math.sin(Math.toRadians($1))");
expr = expr.replaceAll("cos\\((\\d+)\\)", "Math.cos(Math.toRadians($1))");
expr = expr.replaceAll("tan\\((\\d+)\\)", "Math.tan(Math.toRadians($1))");
return eval(expr);
// 预处理表达式,将自定义格式转换为标准格式
String processedExpression = expression.replaceAll("√(\\d+)", "sqrt($1)");
try {
return eval(processedExpression);
} catch (Exception e) {
System.err.println("表达式求值失败: " + expression);
System.err.println("处理后: " + processedExpression);
e.printStackTrace();
throw new IllegalArgumentException("无效的表达式: " + expression, e);
}
}
/**

@ -9,6 +9,7 @@ import java.util.Map;
*/
public class UserManager {
private static final Map<String, UserInfo> users = new HashMap<>();
private static final Map<String, String> usernameToEmail = new HashMap<>(); // 用于检查用户名唯一性
/**
*
@ -16,13 +17,15 @@ public class UserManager {
* @param email
* @param password
* @param gradeType
* @param username
* @return
*/
public boolean register(String email, String password, GradeType gradeType) {
if (users.containsKey(email)) {
public boolean register(String email, String password, GradeType gradeType, String username) {
if (users.containsKey(email) || usernameToEmail.containsKey(username)) {
return false;
}
users.put(email, new UserInfo(email, password, gradeType));
users.put(email, new UserInfo(email, password, gradeType, username));
usernameToEmail.put(username, email);
return true;
}
@ -51,6 +54,16 @@ public class UserManager {
return users.containsKey(email);
}
/**
*
*
* @param username
* @return
*/
public boolean usernameExists(String username) {
return usernameToEmail.containsKey(username);
}
/**
*
*
@ -76,6 +89,7 @@ public class UserManager {
private final String email;
private String password;
private final GradeType gradeType;
private final String username;
/**
*
@ -83,11 +97,13 @@ public class UserManager {
* @param email
* @param password
* @param gradeType
* @param username
*/
public UserInfo(String email, String password, GradeType gradeType) {
public UserInfo(String email, String password, GradeType gradeType, String username) {
this.email = email;
this.password = password;
this.gradeType = gradeType;
this.username = username;
}
/**
@ -116,5 +132,14 @@ public class UserManager {
public GradeType getGradeType() {
return gradeType;
}
/**
*
*
* @return
*/
public String getUsername() {
return username;
}
}
}

@ -54,7 +54,10 @@ public class ChangePasswordDialog extends JDialog {
gbc.fill = GridBagConstraints.HORIZONTAL;
JLabel infoLabel = new JLabel("<html>新密码要求:<br>" +
"长度6-10位,必须包含大小写字母和数字</html>");
"1. 长度 6-10位<br>" +
"2. 必须包含大写字母<br>" +
"3. 必须包含小写字母<br>" +
"4. 必须包含数字</html>");
infoLabel.setFont(new Font("微软雅黑", Font.PLAIN, 11));
gbc.gridx = 0;
gbc.gridy = 0;
@ -126,7 +129,7 @@ public class ChangePasswordDialog extends JDialog {
if (!PASSWORD_PATTERN.matcher(newPassword1).matches()) {
showError("新密码不符合要求:\n" +
"长度6-10位,必须包含大小写字母和数字");
"长度6-10位, 必须包含大小写字母和数字");
return;
}

@ -10,6 +10,7 @@ import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Font;
@ -27,8 +28,9 @@ public class PasswordSetupDialog extends JDialog {
@Serial
private static final long serialVersionUID = 1L;
private static final Pattern PASSWORD_PATTERN =
Pattern.compile("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{6,10}$");
Pattern.compile("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z0-9]{6,10}$");
private final JTextField usernameField;
private final JPasswordField password1Field;
private final JPasswordField password2Field;
private final JComboBox<String> gradeComboBox;
@ -45,12 +47,12 @@ public class PasswordSetupDialog extends JDialog {
* @param email
*/
public PasswordSetupDialog(Frame parent, UserManager userManager, String email) {
super(parent, "设置密码", true);
super(parent, "设置密码和用户名", true);
this.userManager = userManager;
this.email = email;
this.registrationComplete = false;
setSize(600, 380);
setSize(600, 420);
setLocationRelativeTo(parent);
setResizable(true);
@ -61,10 +63,11 @@ public class PasswordSetupDialog extends JDialog {
gbc.fill = GridBagConstraints.HORIZONTAL;
JLabel infoLabel = new JLabel("<html>密码要求:<br>" +
"1. 长度6-10位<br>" +
"1. 长度 6-10位<br>" +
"2. 必须包含大写字母<br>" +
"3. 必须包含小写字母<br>" +
"4. 必须包含数字</html>");
"4. 必须包含数字<br>" +
"5. 不能包含其他特殊字符</html>");
infoLabel.setFont(new Font("微软雅黑", Font.PLAIN, 11));
gbc.gridx = 0;
gbc.gridy = 0;
@ -93,19 +96,29 @@ public class PasswordSetupDialog extends JDialog {
gbc.gridx = 0;
gbc.gridy = 3;
panel.add(new JLabel("设置用户名:"), gbc);
usernameField = new JTextField(20);
gbc.gridx = 1;
gbc.weightx = 1.0;
panel.add(usernameField, gbc);
gbc.weightx = 0.0;
gbc.gridx = 0;
gbc.gridy = 4;
panel.add(new JLabel("选择年级:"), gbc);
String[] grades = {"小学", "初中", "高中"};
gradeComboBox = new JComboBox<>(grades);
gradeComboBox = new JComboBox<>(grades);
gbc.gridx = 1;
gbc.weightx = 1.0;
panel.add(gradeComboBox, gbc);
gbc.weightx = 0.0;
gbc.weightx = 1.0;
panel.add(gradeComboBox, gbc);
gbc.weightx = 0.0;
confirmButton = new JButton("确认注册");
confirmButton.setPreferredSize(new Dimension(120, 30));
gbc.gridx = 0;
gbc.gridy = 4;
gbc.gridy = 5;
gbc.gridwidth = 2;
gbc.anchor = GridBagConstraints.CENTER;
panel.add(confirmButton, gbc);
@ -122,9 +135,15 @@ public class PasswordSetupDialog extends JDialog {
private void handleConfirm() {
String password1 = new String(password1Field.getPassword());
String password2 = new String(password2Field.getPassword());
String username = usernameField.getText().trim();
if (username.isEmpty() || password1.isEmpty() || password2.isEmpty()) {
showError("用户名和密码不能为空");
return;
}
if (password1.isEmpty() || password2.isEmpty()) {
showError("密码不能为空");
if (userManager.usernameExists(username)) {
showError("该用户名已被使用,请更换一个");
return;
}
@ -135,22 +154,22 @@ public class PasswordSetupDialog extends JDialog {
if (!PASSWORD_PATTERN.matcher(password1).matches()) {
showError("密码不符合要求:\n" +
"长度6-10位,必须包含大小写字母和数字");
"长度6-10位, 必须包含大小写字母和数字, 且不能包含特殊字符");
return;
}
GradeType gradeType = getSelectedGradeType();
boolean success = userManager.register(email, password1, gradeType);
boolean success = userManager.register(email, password1, gradeType, username);
if (success) {
JOptionPane.showMessageDialog(this,
"注册成功!",
"注册成功!请返回登录。",
"成功",
JOptionPane.INFORMATION_MESSAGE);
registrationComplete = true;
dispose();
} else {
showError("注册失败,请重试");
showError("注册失败,该邮箱可能已被注册");
}
}

@ -82,9 +82,18 @@ public class QuizFrame extends JFrame {
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
gbc.fill = GridBagConstraints.HORIZONTAL;
// 新增:答案格式提示
JLabel answerFormatLabel = new JLabel("注意:所有计算结果的答案均保留两位小数。", JLabel.CENTER);
answerFormatLabel.setFont(new Font("微软雅黑", Font.ITALIC, 12));
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
centerPanel.add(answerFormatLabel, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 2;
questionLabel = new JLabel();
questionLabel.setFont(new Font("微软雅黑", Font.PLAIN, 18));
@ -98,7 +107,7 @@ public class QuizFrame extends JFrame {
optionButtons[i] = new JRadioButton();
optionButtons[i].setFont(new Font("微软雅黑", Font.PLAIN, 14));
optionGroup.add(optionButtons[i]);
gbc.gridy = i + 1;
gbc.gridy = i + 2;
gbc.gridwidth = 2;
centerPanel.add(optionButtons[i], gbc);
gbc.gridwidth = 1;

@ -31,7 +31,7 @@ import javax.mail.internet.MimeMessage;
public class RegisterDialog extends JDialog {
private static final long serialVersionUID = 1L;
private static final Pattern EMAIL_PATTERN =
Pattern.compile("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$");
Pattern.compile("^[A-Za-z0-9+_.-]+@qq\\.com$");
// 邮件配置 - 请根据实际情况修改
private static final String SMTP_HOST = "smtp.qq.com"; // QQ邮箱SMTP服务器
@ -109,12 +109,12 @@ public class RegisterDialog extends JDialog {
String email = emailField.getText().trim();
if (email.isEmpty()) {
showError("请输入邮箱地址");
showError("邮箱不能为空");
return;
}
if (!EMAIL_PATTERN.matcher(email).matches()) {
showError("邮箱格式不正确");
showError("请输入有效的QQ邮箱(以@qq.com结尾)");
return;
}

Binary file not shown.
Loading…
Cancel
Save