Java课程动脑与课堂实验题目整理

Java 课程动手动脑与课堂实验题目整理

一、动手动脑:线性同余随机数生成器

1.1 题目原文

编写一个方法,使用以下算法生成指定数目(比如 1000 个)的随机整数。

其中使用的算法为线性同余法,数学公式如下:

x(n+1) = (a × x(n) + c) mod m

1.2 算法参数

  • Modulus(模)m = 2^31 - 1 = 2147483647,即 int.MaxValue
  • Multiplier(乘数)a = 7^5 = 16807
  • Increment(增量)c = 0
  • Seed(种子):x0,为随机数序列的初始值
  • 说明:该随机数发生器在输出过 2^31 - 2 个数之后,才可能出现重复

1.3 算法原理

线性同余发生器(Linear Congruential Generator,LCG)是经典的伪随机数生成算法。每次计算时,将当前的随机数 x(n) 代入公式 x(n+1) = (a × x(n) + c) mod m,得到下一个随机数 x(n+1),如此反复迭代即可产生一串随机整数。本例中增量 c = 0,因此也称为“乘同余法”,是 LCG 的一种特例。

由于每次结果都对模 m 取余,生成的数值范围始终落在 [0, m-1] 之间。选择 m = 2^31 - 1、a = 16807 是一组经过验证的经典参数,能够在较长的周期内保证序列的随机性与均匀性。种子 x0 决定整个序列的起点,不同种子会得到不同的随机数序列。

1.4 参考代码(Java)

import java.util.Scanner;

/**

* 线性同余随机数生成器

* 公式:x(n+1) = (a * x(n) + c) mod m

* 参数:m = 2^31 - 1 = 2147483647(int.MaxValue)

* a = 7^5 = 16807,c = 0

*/

public class LinearCongruentialRandom {

// 模 m = 2^31 - 1

private static final long MODULUS = (1L << 31) - 1;

// 乘数 a = 7^5

private static final long MULTIPLIER = 16807;

// 增量 c = 0

private static final long INCREMENT = 0;

private long seed; // 当前值(由种子开始)

/** 构造方法:以指定种子初始化 */

public LinearCongruentialRandom(long seed) {

this.seed = seed;

}

/** 生成下一个随机整数 */

public long next() {

// 将当前值代入公式,得到下一个随机数

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

return seed;

}

public static void main(String[] args) {

Scanner in = new Scanner(System.in);

System.out.print("请输入要生成的随机数个数:");

int count = in.nextInt();

// 以种子 1 开始生成

LinearCongruentialRandom random = new LinearCongruentialRandom(1);

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

System.out.println(i + " : " + random.next());

}

in.close();

}

}

1.5 运行示例

请输入要生成的随机数个数:5

1 : 16807

2 : 282475249

3 : 1622650073

4 : 984943658

5 : 1144108930

1.6 学习指导

在实际开发中,生成随机数是一个比较实用的功能,可以将实现它的相关代码整理并收集起来。在学习过程中应该注意积累和整理各种有用的代码,分门别类地整理好,建立自己的代码仓库,这样一来,在编程时就能快速查找到相应的代码,从而有效地提升自己的开发效率。

使用自己收集整理的资料库,通常比使用搜索引擎查找资料要高效得多。

二、课堂测试一(阶段1):小学四则运算题目生成器

2.1 背景故事(疑问看故事)

一家软件公司的程序员二柱,小孩上了小学二年级,老师让家长每天出 30 道四则运算题目给小学生做。

二柱立马就想到写一个小程序来做这件事。这个事情可以用很多语言或者工具来实现:Excel、C/C++、C#、VB、Unix Shell、Emacs、Powershell/Vbscript、Javascript、Perl、Python……

请大家估计写好这个程序需要的时间。我想程序员用自己最擅长的工具,一支烟的功夫就搞定了。

2.2 题目原文

阶段1:像二柱子那样,花二十分钟写一个能自动生成 30 道小学四则运算题目的“软件”。

2.3 需求要点

  • 一次性输出 30 道四则运算算式(加、减、乘、除)
  • 数字范围适合小学二年级水平(这里取 1~100 的整数)
  • 在控制台打印题目即可

2.4 参考代码(Java)

import java.util.Random;

/**

* 小学四则运算题目生成器(阶段1)

* 自动生成 30 道加减乘除算式

*/

public class ArithmeticGenerator {

public static void main(String[] args) {

Random random = new Random();

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

// 随机生成 1~100 的两个整数

int a = random.nextInt(100) + 1;

int b = random.nextInt(100) + 1;

// 从 + - * / 中随机选一个运算符

char[] ops = {'+', '-', '*', '/'};

char op = ops[random.nextInt(ops.length)];

// 输出题目

System.out.println("(" + (i + 1) + ") " + a + " " + op + " " + b + " = ");

}

}

}

2.5 运行示例

(1) 56 + 23 =

(2) 78 - 45 =

(3) 12 * 8 =

(4) 90 / 6 =

(5) 34 + 17 =

…… (共 30 道)

三、课堂测试二(阶段2):四则运算增强版

3.1 题目原文

阶段2:(1)要求题目避免重复,减法不允许出现负数。

3.2 需求要点(阶段1 + 阶段2 约束)

  • 一共生成 30 道题目,题目不能重复
  • 减法运算不允许出现负数(被减数 ≥ 减数)
  • 除法运算结果为整数(整除),除数不为 0

3.3 参考代码(Java)

import java.util.HashSet;

import java.util.Random;

import java.util.Set;

/**

* 小学四则运算题目生成器(阶段2·增强版)

* 约束:题目不重复;减法不出负数;除法整除且除数不为0

*/

public class EnhancedArithmeticGenerator {

public static void main(String[] args) {

Random random = new Random();

Set<String> used = new HashSet<>(); // 记录已生成的题目,避免重复

int count = 0; // 已生成题目数

while (count < 30) {

int a = random.nextInt(100) + 1; // 1~100

int b = random.nextInt(100) + 1; // 1~100

char[] ops = {'+', '-', '*', '/'};

char op = ops[random.nextInt(ops.length)];

// 约束1:减法不允许出现负数 -> 保证 a >= b

if (op == '-') {

if (a < b) {

int t = a; a = b; b = t; // 交换,使 a >= b

}

}

// 约束2:除法要整除、除数不为0 -> 将 b 调整为 a 的因子

if (op == '/') {

if (b == 0) b = 1;

a = (a / b) * b; // 使 a 是 b 的整数倍

if (b == 0) b = 1;

}

String question = a + " " + op + " " + b + " = ";

// 约束3:题目不重复

if (used.contains(question)) {

continue; // 已出现过,重新生成

}

used.add(question);

System.out.println("(" + (count + 1) + ") " + question);

count++;

}

}

}

3.4 运行示例

(1) 56 + 23 =

(2) 78 - 45 =

(3) 12 * 8 =

(4) 90 / 6 =

(5) 34 - 34 =

…… (共 30 道,且均不重复)

四、练习:方法重载——查看 System.out.println()

4.1 知识点:方法重载的要点

在 Java 中,满足以下条件的两个或多个方法构成“重载(overload)”关系:

  • (1)方法名相同;
  • (2)参数类型不同,参数个数不同,或者是参数类型的顺序不同。

注意:方法的返回值不作为方法重载的判断条件。也就是说,即使返回值不同,只要方法名和参数列表相同,也不能构成重载。

4.2 练习原文

查看一下 JDK 中 System.out.println() 方法,你发现了什么?

4.3 观察与结论

System.out.println() 是 Java 中最常用的输出方法之一。通过查看 JDK 源码可以发现,System.out 是一个 PrintStream 类型的对象,而 PrintStream 类中定义了大量名为 println 的方法,它们方法名完全相同,但参数列表各不相同,例如:println()、println(char)、println(int)、println(long)、println(float)、println(double)、println(boolean)、println(char[])、println(String)、println(Object) 等。

这正是“方法重载”的典型体现:方法名统一为 println,通过不同的参数类型(String、int、double、boolean、Object……)来自动匹配并输出对应的内容。我们在调用 System.out.println() 时传入不同类型的参数,编译器会自动选择参数匹配的重载版本,这正是方法重载带给编程的便利。

4.4 参考代码(Java)

/**

* 演示:自定义一个支持多种参数类型的 println 方法(模拟方法重载)

*/

public class PrintlnDemo {

// 重载:方法名相同,参数类型不同

public static void println(int x) {

System.out.println("整数: " + x);

}

public static void println(double x) {

System.out.println("小数: " + x);

}

public static void println(String s) {

System.out.println("字符串: " + s);

}

public static void println(boolean b) {

System.out.println("布尔: " + b);

}

public static void println(Object o) {

System.out.println("对象: " + o);

}

public static void main(String[] args) {

// 编译器按参数类型自动选择对应的重载方法

println(10); // int

println(3.14); // double

println("你好,Java"); // String

println(true); // boolean

println(new PrintlnDemo()); // Object

}

}

4.5 运行示例

整数: 10

小数: 3.14

字符串: 你好,Java

布尔: true

对象: PrintlnDemo@15db9742

posted @ 2026-10-08 14:42  刘秋实  阅读(5)  评论(0)    收藏  举报