9.24方法PPT课后

  1. 编写一个方法,使用纯随机数发生器生成指定数目(比如1000个)的随机整数。

import java.util.ArrayList;

import java.util.List;

public class RandomGenerator {

// 固定参数:和题目对应

private static final long MODULUS = (1L << 31) - 1; // 2^31 -1,注意用long避免溢出

private static final long MULTIPLIER = 16807; // 即7^5

private static final long C = 0;

// 种子:需要初始化,默认可以用当前时间戳

private long seed;

/**

* 用自定义种子构造生成器

* @param seed 初始种子 不能是0,否则生成的所有数都是0

*/

public RandomGenerator(long seed) {

if (seed == 0) {

throw new IllegalArgumentException("种子不能为0");

}

// 保证种子在模数范围内

this.seed = seed % MODULUS;

}

/**

* 默认用当前时间戳作为种子

*/

public RandomGenerator() {

this(System.currentTimeMillis());

}

/**

* 生成下一个随机整数

* @return 范围在 [1, 2^31-2] 的随机整数

*/

public int nextInt() {

// 用long计算防止整数溢出

seed = (MULTIPLIER * seed + C) % MODULUS;

// 因为范围是1~2^31-2,强转为int正好是合法的正整数

return (int) seed;

}

/**

* 生成指定数量的随机整数

* @param count 要生成的个数

* @return 随机数列表

*/

public List<Integer> generate(int count) {

if (count <= 0) {

throw new IllegalArgumentException("生成数量必须大于0");

}

List<Integer> res = new ArrayList<>(count);

for (int i = 0; i < count; i++) {

res.add(nextInt());

}

return res;

}

// 测试:生成1000个随机数

public static void main(String[] args) {

RandomGenerator generator = new RandomGenerator();

// 生成1000个随机数

List<Integer> randomNumbers = generator.generate(1000);

// 输出前20个做演示,避免打印太多

System.out.println("前20个生成的随机数:");

for (int i = 0; i < 20; i++) {

System.out.printf("%d\t", randomNumbers.get(i));

if ((i + 1) % 5 == 0) {

System.out.println();

}

}

}

}

  1. 以下代码的特殊之处

这段代码的特殊之处在于它展示了方法重载的概念。方法重载是指在同一个类中,允许存在多个同名方法,但这些方法的参数列表必须不同(参数的类型、个数或顺序不同)。

具体到这段代码:

  1. 定义了两个同名方法 square,一个接受 int 类型的参数,另一个接受 double 类型的参数。
  2. 在 main 方法中,分别调用了这两个重载方法:
    • square(7) 调用的是接受 int 参数的方法,返回 7 * 7 = 49。
    • square(7.5) 调用的是接受 double 参数的方法,返回 7.5 * 7.5 = 56.25
  3. 像二柱子那样,花二十分钟写一个能自动生成30道小学四则运算题目的 “软件”

import java.util.Random;

public class ArithmeticGenerator {

public static void main(String[] args) {

System.out.println("--- 小学二年级四则运算自动生成器 ---");

System.out.println("-------------------------------------");

// 循环生成30道题目

for (int i = 1; i <= 30; i++) {

String question = generateQuestion();

// 格式化输出,每行显示5道题,方便打印

System.out.printf("%-2d. %-15s", i, question);

if (i % 3 == 0) { // 每3道题换一行(也可以改成5)

System.out.println();

}

}

}

/**

* 生成单道题目的方法

*/

public static String generateQuestion() {

Random random = new Random();

// 随机选择运算符:0:+, 1:-, 2:*, 3:/

int operatorType = random.nextInt(4);

int num1, num2;

String operator = "";

int result = 0;

switch (operatorType) {

case 0: // 加法

// 限制在100以内

num1 = random.nextInt(50) + 1;

num2 = random.nextInt(50) + 1;

operator = "+";

break;

case 1: // 减法

// 保证 num1 >= num2,结果不为负数

num1 = random.nextInt(100) + 1;

num2 = random.nextInt(num1) + 1; // 生成 1 到 num1 之间的数

operator = "-";

break;

case 2: // 乘法

// 小学二年级乘法通常使用乘法口诀表范围 (1-9)

num1 = random.nextInt(9) + 1;

num2 = random.nextInt(9) + 1;

operator = "×";

break;

case 3: // 除法

default:

// 保证能整除

num2 = random.nextInt(9) + 1; // 除数 1-9

int multiplier = random.nextInt(9) + 1; // 商 1-9

num1 = num2 * multiplier; // 被除数 = 除数 * 商

operator = "÷";

break;

}

return num1 + " " + operator + " " + num2 + " =";

}

}

  1. (1)要求题目避免重复,减法不允许出现负数,乘法结果不允许出现四位数,除法必须整除不允许出现小数;

(2)实现在线实时答题,并在答题结束后,统计显示错题数,正确率;

(3)增加倒计时功能,要求在指定时间内完成测试,超时未做完视为错题。

import javax.swing.*;

import java.awt.*;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.util.HashSet;

import java.util.Random;

import java.util.Set;

public class ArithmeticTestGUI extends JFrame {

private static final int TOTAL_QUESTIONS = 20; // 每轮题目数量,参考图片大约20道

private static final int TIME_LIMIT_SECONDS = 300; // 倒计时时间(秒),例如5分钟

private JTextField[] answerFields = new JTextField[TOTAL_QUESTIONS];

private String[] questions = new String[TOTAL_QUESTIONS];

private int[] correctAnswers = new int[TOTAL_QUESTIONS];

private long startTime;

private int timeRemaining = TIME_LIMIT_SECONDS;

private Timer countdownTimer;

private boolean isSubmitted = false;

public ArithmeticTestGUI() {

// 1. 初始化窗口设置

setTitle("整数四则运算测试");

setSize(900, 600);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setLocationRelativeTo(null); // 居中显示

setLayout(new BorderLayout(10, 10));

// 2. 生成题目

generateQuestions();

// 3. 构建顶部信息面板

JPanel topPanel = new JPanel(new BorderLayout());

JLabel infoLabel = new JLabel(" 201571030128 王静雅的第1轮测试...", JLabel.LEFT);

infoLabel.setFont(new Font("宋体", Font.BOLD, 14));

topPanel.add(infoLabel, BorderLayout.WEST);

// (可选) 顶部可以放倒计时,但图片中没有直观显示倒计时在界面上,所以我们在后台运行,最后弹窗提示

add(topPanel, BorderLayout.NORTH);

// 4. 构建中间题目面板 (4列5行的网格)

JPanel centerPanel = new JPanel(new GridLayout(5, 4, 10, 20));

centerPanel.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));

for (int i = 0; i < TOTAL_QUESTIONS; i++) {

JPanel qPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

JLabel qLabel = new JLabel(questions[i] + " =");

qLabel.setFont(new Font("Arial", Font.PLAIN, 14));

answerFields[i] = new JTextField(4);

answerFields[i].setFont(new Font("Arial", Font.PLAIN, 14));

qPanel.add(qLabel);

qPanel.add(answerFields[i]);

centerPanel.add(qPanel);

}

add(centerPanel, BorderLayout.CENTER);

// 5. 构建底部按钮面板

JPanel bottomPanel = new JPanel();

JButton submitButton = new JButton("查看得分");

submitButton.setFont(new Font("宋体", Font.BOLD, 14));

submitButton.setPreferredSize(new Dimension(120, 35));

bottomPanel.add(submitButton);

add(bottomPanel, BorderLayout.SOUTH);

// 6. 绑定交卷事件

submitButton.addActionListener(e -> submitTest(false));

// 7. 启动倒计时

startTimer();

}

private void startTimer() {

startTime = System.currentTimeMillis();

countdownTimer = new Timer(1000, new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

timeRemaining--;

if (timeRemaining <= 0) {

countdownTimer.stop();

submitTest(true); // 超时交卷

}

}

});

countdownTimer.start();

}

private void submitTest(boolean isTimeout) {

if (isSubmitted) return; // 防止重复提交

isSubmitted = true;

if (countdownTimer != null) {

countdownTimer.stop();

}

long endTime = System.currentTimeMillis();

long timeSpentSeconds = (endTime - startTime) / 1000;

int wrongCount = 0;

// 遍历检查答案

for (int i = 0; i < TOTAL_QUESTIONS; i++) {

String userAnswerStr = answerFields[i].getText().trim();

if (userAnswerStr.isEmpty()) {

wrongCount++; // 未作答视为错题

continue;

}

try {

int userAnswer = Integer.parseInt(userAnswerStr);

if (userAnswer != correctAnswers[i]) {

wrongCount++;

}

} catch (NumberFormatException e) {

wrongCount++; // 输入非数字视为错题

}

}

int correctCount = TOTAL_QUESTIONS - wrongCount;

double accuracy = (double) correctCount / TOTAL_QUESTIONS * 100;

// 弹出成绩对话框

String message;

if (isTimeout) {

message = String.format("时间到!自动交卷。\n\n本次用时:%d 秒\n错题数:%d 题\n正确率:%.1f%%",

timeSpentSeconds, wrongCount, accuracy);

} else {

message = String.format("您本次用时:%d 秒\n错题数:%d 题\n正确率:%.1f%%",

timeSpentSeconds, wrongCount, accuracy);

}

JOptionPane.showMessageDialog(this, message, "测试结果", JOptionPane.INFORMATION_MESSAGE);

// 禁用所有输入框,防止交卷后修改

for (JTextField field : answerFields) {

field.setEnabled(false);

}

}

private void generateQuestions() {

Random random = new Random();

Set<String> questionSet = new HashSet<>(); // 用于去重

int count = 0;

while (count < TOTAL_QUESTIONS) {

// 随机决定这道题有几个运算符 (1个或2个,太复杂不适合口算)

int operatorCount = random.nextInt(2) + 1;

String question = "";

int result = 0;

if (operatorCount == 1) {

// 简单题:A op B

int[] nums = new int[2];

char[] ops = new char[1];

if (generateSimpleExpression(random, nums, ops)) {

question = nums[0] + " " + ops[0] + " " + nums[1];

result = calculate(nums[0], nums[1], ops[0]);

} else {

continue;

}

} else {

// 复杂题:A op1 B op2 C (形如 55*18+89 等)

int[] nums = new int[3];

char[] ops = new char[2];

if (generateComplexExpression(random, nums, ops)) {

question = nums[0] + " " + ops[0] + " " + nums[1] + " " + ops[1] + " " + nums[2];

// 按照从左到右计算(默认无括号),若需支持括号需特殊处理,此处简化处理,保持与图一致

int temp = calculate(nums[0], nums[1], ops[0]);

result = calculate(temp, nums[2], ops[1]);

} else {

continue;

}

}

// 去重逻辑

if (!questionSet.contains(question) && result >= 0) {

questions[count] = question;

correctAnswers[count] = result;

questionSet.add(question);

count++;

}

}

}

// 生成简单的单运算符表达式,满足约束

private boolean generateSimpleExpression(Random random, int[] nums, char[] ops) {

int opType = random.nextInt(4); // 0:+, 1:-, 2:*, 3:/

int a, b;

switch (opType) {

case 0: // 加法:限制在100以内

a = random.nextInt(50) + 1;

b = random.nextInt(50) + 1;

nums[0] = a; nums[1] = b; ops[0] = '+';

return true;

case 1: // 减法:不出现负数

a = random.nextInt(100) + 1;

b = random.nextInt(a) + 1; // b <= a

nums[0] = a; nums[1] = b; ops[0] = '-';

return true;

case 2: // 乘法:结果不出现四位数 (<=999,即a*b < 1000)

a = random.nextInt(99) + 1;

b = random.nextInt(99) + 1;

if (a * b > 999) return false;

nums[0] = a; nums[1] = b; ops[0] = '*';

return true;

case 3: // 除法:必须整除,不出现小数

b = random.nextInt(99) + 1;

int tempResult = random.nextInt(99) + 1;

a = b * tempResult;

nums[0] = a; nums[1] = b; ops[0] = '/';

return true;

}

return false;

}

// 生成复杂的双运算符表达式 (如 A*B+C)

private boolean generateComplexExpression(Random random, int[] nums, char[] ops) {

// 为保证结果合理,通常第一个运算符优先级较高(乘除),或者第一个是加减法

// 这里为了简化,模拟图片中的题型,生成形如 a*b+c 或 a+b*c 等

int type = random.nextInt(4);

int a, b, c;

// 此处只做基础校验,保证每步计算都不越界

try {

switch (type) {

case 0: // a * b + c

a = random.nextInt(20) + 1; b = random.nextInt(20) + 1;

if (a * b > 999) return false;

c = random.nextInt(100) + 1;

nums[0]=a; nums[1]=b; nums[2]=c; ops[0]='*'; ops[1]='+';

return true;

case 1: // a + b * c

a = random.nextInt(100) + 1;

b = random.nextInt(20) + 1; c = random.nextInt(20) + 1;

if (b * c > 999) return false;

nums[0]=a; nums[1]=b; nums[2]=c; ops[0]='+'; ops[1]='*';

return true;

case 2: // a * b - c

a = random.nextInt(20) + 1; b = random.nextInt(20) + 1;

if (a * b > 999 || a * b < 1) return false;

c = random.nextInt(a * b) + 1; // 保证减去后不为负数

nums[0]=a; nums[1]=b; nums[2]=c; ops[0]='*'; ops[1]='-';

return true;

case 3: // a / b + c

b = random.nextInt(20) + 1;

int res = random.nextInt(20) + 1;

a = b * res;

c = random.nextInt(100) + 1;

nums[0]=a; nums[1]=b; nums[2]=c; ops[0]='/'; ops[1]='+';

return true;

}

} catch (Exception e) {

return false;

}

return false;

}

// 计算单步结果

private int calculate(int a, int b, char op) {

switch (op) {

case '+': return a + b;

case '-': return a - b;

case '*': return a * b;

case '/': return b != 0 ? a / b : 0;

}

return 0;

}

public static void main(String[] args) {

// 在事件调度线程中运行GUI

SwingUtilities.invokeLater(() -> {

new ArithmeticTestGUI().setVisible(true);

});

}

}

posted @ 2026-10-07 19:34  雾蒙蒙o  阅读(5)  评论(0)    收藏  举报