2024/10/15日 日志 ---》对多年级多需求四则运算的初步解决
昨天我们进行了一次小的题目测试,题目的主体为四则运算。
1、可定制(数量):输入大的出题数量值,测试一下系统是否崩溃,反向查找系统是否优化的余地;
2、定制操作数的个数、定制是否有乘除法、定制是否有括号(随机加入)、定制数值范围(确定操作数的取值范围);
3、定义方法实现错题集、错题重练并记录错题的次数功能。
4、能处理大数和浮点数计算。
5、要求可以同时定义小学二年级口算题、小学三年级口算题、小学四年级口算题。
(1)小学二年级口算题操作数为两个、可进行加减乘除运算(除法必须可以整除),操作数范围不超过100。
(2)小学三年级口算题操作数不超过4个,可以进行加减乘除,操作数范围不超过1000.(要求采用继承小学二年级出题类的方式,实现小学三年级的出题类)。
(3)小学四年级口算题操作数不超过5个,可以进行加减乘除,还可以加入括号运算。 (要求采用继承小学三年级出题类的方式,实现小学四年级的出题类)。
6、学生实时答题结束后,可以选择是否进行下一套题目答题,如果选择是,则抽取下一套题进行答题,答题结束可以通过查看错题本,查询今日做题正确率阶段;也可以针对错题进行二次答题。
7、要求将题目输出到文本文件中,三题一行,用户做完后,将文本导入,判读正误,显示统计结果。
基于昨日时间仓促,只对题目有了架构但没实现,今天对其进行了初步实现:
Moontest.java
点击查看代码
//张一衡 20234023
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Timer;
public class Moontest {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请选择年级(2/3/4):");
int grade = scanner.nextInt();
System.out.println("请输入出题数量:");
int numQuestions = scanner.nextInt();
CountJFrame frame = new CountJFrame(grade, numQuestions);
boolean continueTesting = true;
while (continueTesting) {
System.out.println("是否进行下一套题目答题(y/n)?");
String choice = scanner.next();
if (choice.equalsIgnoreCase("y")) {
System.out.println("请输入出题数量:");
numQuestions = scanner.nextInt();
frame = new CountJFrame(grade, numQuestions);
} else {
continueTesting = false;
}
}
System.out.println("是否查看错题本(y/n)?");
String viewWrongChoice = scanner.next();
if (viewWrongChoice.equalsIgnoreCase("y")) {
try {
BufferedWriter writer = new BufferedWriter(new FileWriter("wrong_answers.txt"));
for (Operation wrongAnswer : frame.wrongAnswers) {
writer.write(wrongAnswer.toString() + " (正确答案: " + wrongAnswer.result + ")\n");
}
writer.close();
System.out.println("错题已保存到 wrong_answers.txt 文件中。");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Operation.java
点击查看代码
class Operation {
int num1;
int num2;
char operator;
int result;
// 用于嵌套运算
Operation nestedOperation; // 可能是另一个Operation实例
public Operation(int n1, int n2, char op) {
num1 = n1;
num2 = n2;
operator = op;
calculateResult();
}
// 用于嵌套运算的构造函数
public Operation(Operation nestedOp, int n, char op) {
this.nestedOperation = nestedOp;
this.num2 = n;
this.operator = op;
calculateResult();
}
private void calculateResult() {
int value1 = (nestedOperation != null) ? nestedOperation.result : num1; // 如果有嵌套运算,使用其结果
switch (operator) {
case '+':
result = value1 + num2;
break;
case '-':
result = value1 - num2;
break;
case '*':
result = value1 * num2;
break;
case '/':
if (num2 != 0 && value1 % num2 == 0) {
result = value1 / num2;
}
break;
}
}
@Override
public String toString() {
if (nestedOperation != null) {
return "(" + nestedOperation + ") " + operator + " " + num2 + " =?";
} else {
return num1 + " " + operator + " " + num2 + " =?";
}
}
}
Grade2.java
点击查看代码
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Grade2{
protected Random random = new Random();
protected List<Operation> operations = new ArrayList<>();
public Grade2(int numQuestions) {
generateQuestions(numQuestions);
}
protected void generateQuestions(int numQuestions) {
for (int i = 0; i < numQuestions; i++) {
int num1 = random.nextInt(100);
int num2 = random.nextInt(100);
char operator;
switch (random.nextInt(4)) {
case 0:
operator = '+';
break;
case 1:
operator = '-';
break;
case 2:
operator = '*';
break;
case 3:
operator = '/';
break;
default:
operator = '+';
}
operations.add(new Operation(num1, num2, operator));
}
}
public List<Operation> getOperations() {
return operations;
}
}
Grade3.java
点击查看代码
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Grade3 extends Grade2{
public Grade3(int numQuestions) {
super(numQuestions);
for (Operation operation : operations) {
// 如果是除法且除数为0,重新生成除数
if (operation.operator == '/') {
while (operation.num2 == 0) {
operation.num2 = random.nextInt(999) + 1; // 确保除数不为0
}
}
operation.num1 = random.nextInt(1000);
operation.num2 = random.nextInt(1000);
operation = new Operation(operation.num1, operation.num2, operation.operator); // 重新生成Operation
}
}
}
Grade4.java
点击查看代码
import java.util.List;
import java.util.Random;
public class Grade4 extends Grade3 {
private Random random = new Random();
public Grade4(int numQuestions) {
super(numQuestions);
}
@Override
protected void generateQuestions(int numQuestions) {
super.generateQuestions(numQuestions); // 先生成基础的操作
for (int i = 0; i < operations.size(); i++) {
Operation operation = operations.get(i);
// 随机给操作数加上额外的值
if (random.nextBoolean()) {
operation.num1 = (int) ((random.nextDouble() * 1000) + operation.num1);
operation.num2 = (int) ((random.nextDouble() * 1000) + operation.num2);
}
// 随机决定是否添加括号
if (random.nextBoolean()) {
operations.set(i, addParentheses(operation)); // 更新操作为带括号的版本
}
}
}
// 添加括号的逻辑
private Operation addParentheses(Operation operation) {
int n1 = operation.num1;
int n2 = operation.num2;
char op = operation.operator;
// 随机决定括号的放置
int n3 = random.nextInt(1000); // 随机生成 n3
if (random.nextBoolean()) {
// (n1 op n2) op n3
return new Operation(new Operation(n1, n2, op), n3, random.nextBoolean() ? '+' : '-');
} else {
// n1 op (n2 op n3)
Operation nestedOperation = new Operation(n2, n3, random.nextBoolean() ? '+' : '-'); // 创建一个嵌套操作
return new Operation(n1, nestedOperation.result, op);
}
}
}
CountJFrame.java
点击查看代码
import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
class CountJFrame extends JFrame {
List<Operation> operations;
JTextField[] inputFields;
JLabel timerLabel;
Timer timer;
int remainingTime = 180;
List<Operation> wrongAnswers = new ArrayList<>();
public CountJFrame(int grade, int numQuestions) {
switch (grade) {
case 2:
operations = new Grade2(numQuestions).getOperations();
break;
case 3:
operations = new Grade3(numQuestions).getOperations();
break;
case 4:
operations = new Grade4(numQuestions).getOperations();
break;
}
initJFrame();
initView();
startTimer();
this.setVisible(true);
}
private void initJFrame() {
this.setSize(500, 400);
this.setTitle("四则运算--升级版");
this.setAlwaysOnTop(true);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setLayout(null);
}
private void initView() {
int numQuestions = operations.size();
inputFields = new JTextField[numQuestions];
timerLabel = new JLabel("剩余时间: " + remainingTime + "秒");
timerLabel.setBounds(10, 10, 200, 30);
this.getContentPane().add(timerLabel);
JPanel questionPanel = new JPanel();
questionPanel.setLayout(new GridLayout(0, 2, 10, 10));
for (int i = 0; i < numQuestions; i++) {
JLabel questionLabel = new JLabel(operations.get(i).toString());
questionLabel.setBorder(new BevelBorder(BevelBorder.LOWERED));
questionPanel.add(questionLabel);
inputFields[i] = new JTextField();
questionPanel.add(inputFields[i]);
}
JScrollPane scrollPane = new JScrollPane(questionPanel);
scrollPane.setBounds(10, 50, 460, 250);
this.getContentPane().add(scrollPane);
JButton submitButton = new JButton("提交");
submitButton.setBounds(380, 310, 80, 30);
submitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
StringBuilder incorrectAnswers = new StringBuilder();
boolean allCorrect = true;
for (int i = 0; i < inputFields.length; i++) {
String userInput = inputFields[i].getText();
if (!userInput.equals(String.valueOf(operations.get(i).result))) {
incorrectAnswers.append(operations.get(i)).append(" (正确答案: ")
.append(operations.get(i).result).append(")\n");
allCorrect = false;
wrongAnswers.add(operations.get(i));
}
}
JDialog dialog = new JDialog(CountJFrame.this, "结果", true);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setAlwaysOnTop(true);
dialog.setLocationRelativeTo(CountJFrame.this);
if (allCorrect) {
JOptionPane.showMessageDialog(dialog, "所有答案正确!");
} else {
JOptionPane.showMessageDialog(dialog, "有答案不正确,请查看:\n" + incorrectAnswers.toString());
}
timer.stop();
}
});
this.getContentPane().add(submitButton);
}
private void startTimer() {
timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
remainingTime--;
timerLabel.setText("剩余时间: " + remainingTime + "秒");
if (remainingTime <= 0) {
timer.stop();
JOptionPane.showMessageDialog(null, "时间到,请提交答案!");
StringBuilder incorrectAnswers = new StringBuilder();
boolean allCorrect = true;
for (int i = 0; i < inputFields.length; i++) {
String userInput = inputFields[i].getText();
if (!userInput.equals(String.valueOf(operations.get(i).result))) {
incorrectAnswers.append(operations.get(i)).append(" (正确答案: ")
.append(operations.get(i).result).append(")\n");
allCorrect = false;
wrongAnswers.add(operations.get(i));
}
}
if (allCorrect) {
JOptionPane.showMessageDialog(null, "所有答案正确!");
} else {
JOptionPane.showMessageDialog(null, "有答案不正确,请查看:\n" + incorrectAnswers.toString());
}
}
}
});
timer.start();
}
}
尽管如此,但程序仍不能完全满足题目需求,甚至对一些需求进行了简化处理,Grade4的括号问题是目前无从下手的地方,亟待解决。
接下来,我将继续修改优化代码,对简化处理部分进行复原并更改原有基础结构以完成题目要求。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署