作业1
Java方法课程:动手动脑与实验问题总结
一、引言
本博客整理了《Java语言程序设计》第二讲"方法"课程中的所有动手动脑问题以及课后实验性问题。通过这些问题,我们深入理解了Java方法的定义、使用、重载、递归等核心概念,并掌握了处理大数字和浮点数的方法。
---
二、动手动脑问题详解
1. 随机数生成器实现
要求:编写一个方法,使用线性同余生成器(LCG)算法生成指定数量的随机整数。
算法参数:
· Modulus = 2³¹ - 1 = 2147483647
· Multiplier = 16807
· C = 0
实现代码:
```java
public class RandomGenerator {
******** private static final long MODULUS = 2147483647L;********
******** private static final long MULTIPLIER = 16807L;********
******** private static long seed = System.currentTimeMillis();********
******** /**********
******** * 使用LCG算法生成随机整数********
******** * @return 0到MODULUS-1之间的随机整数********
******** /*******
******** public static int nextInt() {********
******** seed = (MULTIPLIER * seed) % MODULUS;********
******** return (int) seed;********
******** }********
******** /**********
******** * 生成指定数量的随机整数********
******** * @param count 要生成的随机数数量********
******** * @return 随机整数数组********
******** /*******
******** public static int[] generateRandomNumbers(int count) {********
******** int[] numbers = new int[count];********
******** for (int i = 0; i < count; i++) {********
******** numbers[i] = nextInt();********
******** }********
******** return numbers;********
******** }********
******** // 测试方法********
******** public static void main(String[] args) {********
******** int[] randomNumbers = generateRandomNumbers(10);********
******** System.out.println("生成的随机数:");********
******** for (int num : randomNumbers) {********
******** System.out.println(num);********
******** }********
******** }********
}
```
算法特点:
· 周期为2³¹-2,几乎不会重复
· 算法简单,计算速度快
· 适合教学和理解随机数生成原理
2. 方法重载观察
观察代码:
```java
public class MethodOverLoad {
******** // 方法1:两个int参数********
******** public static void print(int a, int b) {********
******** System.out.println("两个int参数: " + a + ", " + b);********
******** }********
******** // 方法2:三个int参数********
******** public static void print(int a, int b, int c) {********
******** System.out.println("三个int参数: " + a + ", " + b + ", " + c);********
******** }********
******** // 方法3:两个double参数********
******** public static void print(double a, double b) {********
******** System.out.println("两个double参数: " + a + ", " + b);********
******** }********
******** // 方法4:int和double参数********
******** public static void print(int a, double b) {********
******** System.out.println("int和double参数: " + a + ", " + b);********
******** }********
******** // 方法5:double和int参数 - 参数顺序不同********
******** public static void print(double a, int b) {********
******** System.out.println("double和int参数: " + a + ", " + b);********
******** }********
******** // 注意:以下方法不能构成重载,编译错误********
******** // public static int print(int a, int b) {********
******** // System.out.println("返回值不同的方法");********
******** // return a + b;********
******** // }********
******** public static void main(String[] args) {********
******** print(1, 2);********
******** print(1, 2, 3);********
******** print(1.5, 2.5);********
******** print(1, 2.5);********
******** print(1.5, 2);********
******** }********
}
```
方法重载要点:
· ✅ 方法名必须相同
· ✅ 参数类型不同
· ✅ 参数个数不同
· ✅ 参数类型顺序不同
· ❌ 返回值类型不同不构成重载
3. System.out.println()方法观察
观察结果:
通过查看JDK源码,发现System.out.println()方法有多个重载版本:
java******** ********// 部分重载方法示例******** ********public void println() {} // 打印空行******** ********public void println(boolean x) {} // 打印boolean******** ********public void println(char x) {} // 打印char******** ********public void println(int x) {} // 打印int******** ********public void println(long x) {} // 打印long******** ********public void println(float x) {} // 打印float******** ********public void println(double x) {} // 打印double******** ********public void println(char x[]) {} // 打印char数组******** ********public void println(String x) {} // 打印String******** ********public void println(Object x) {} // 打印Object******** ********
发现:
· println方法针对所有基本数据类型和常用引用类型都提供了重载版本
· 这种设计使得用户可以使用统一的方法名打印不同类型的数据
· 体现了Java"一次编写,到处运行"的设计理念
---
三、课后实验问题实现
1. 四则运算题目生成器(阶段1)
要求:20分钟内完成能自动生成30道小学四则运算题目的程序。
实现代码:
```java
import java.util.Random;
public class ArithmeticGeneratorV1 {
******** private static Random random = new Random();********
******** public static void main(String[] args) {********
******** generateQuestions(30);********
******** }********
******** /**********
******** * 生成指定数量的四则运算题目********
******** * @param count 题目数量********
******** /*******
******** public static void generateQuestions(int count) {********
******** System.out.println("小学四则运算题目(共" + count + "题)😊;********
******** System.out.println("====================");********
******** for (int i = 1; i <= count; i++) {********
******** String question = generateSingleQuestion();********
******** System.out.println(i + ". " + question);********
******** }********
******** }********
******** /**********
******** * 生成单个题目********
******** * @return 题目字符串********
******** /*******
******** private static String generateSingleQuestion() {********
******** int num1 = random.nextInt(100) + 1; // 1-100********
******** int num2 = random.nextInt(100) + 1; // 1-100********
******** char operator = getRandomOperator();********
******** return num1 + " " + operator + " " + num2 + " = ";********
******** }********
******** /**********
******** * 随机获取运算符********
******** * @return 运算符字符********
******** /*******
******** private static char getRandomOperator() {********
******** char[] operators = {'+', '-', '×', '÷'};********
******** return operators[random.nextInt(operators.length)];********
******** }********
}
```
2. 四则运算题目生成器(阶段2)
增强要求:
· 题目避免重复
· 减法不允许出现负数
· 乘法结果不允许出现四位数
· 除法必须整除,不允许出现小数
· 实现在线实时答题
· 统计错题数和正确率
· 增加倒计时功能
完整实现代码:
```java
import java.util.*;
import java.util.concurrent.TimeUnit;
public class ArithmeticGeneratorV2 {
******** private static Random random = new Random();********
******** private static Scanner scanner = new Scanner(System.in);********
******** private static Set
******** public static void main(String[] args) {********
******** startTest();********
******** }********
******** /**********
******** * 开始测试********
******** /*******
******** public static void startTest() {********
******** System.out.println("欢迎参加四则运算测试!");********
******** System.out.println("测试规则:");********
******** System.out.println("1. 共30道题目");********
******** System.out.println("2. 时间限制:5分钟");********
******** System.out.println("3. 超时未完成视为错题");********
******** System.out.println("====================");********
******** // 生成题目********
******** String[] questions = generateUniqueQuestions(30);********
******** int[] correctAnswers = calculateAnswers(questions);********
******** // 开始答题********
******** int score = takeTest(questions, correctAnswers, 300); // 5分钟=300秒********
******** // 显示结果********
******** showResult(score, questions.length);********
******** }********
******** /**********
******** * 生成不重复的题目********
******** * @param count 题目数量********
******** * @return 题目数组********
******** /*******
******** public static String[] generateUniqueQuestions(int count) {********
******** String[] questions = new String[count];********
******** int generated = 0;********
******** while (generated < count) {********
******** String question = generateValidQuestion();********
******** if (!generatedQuestions.contains(question)) {********
******** questions[generated] = question;********
******** generatedQuestions.add(question);********
******** generated++;********
******** }********
******** }********
******** return questions;********
******** }********
******** /**********
******** * 生成符合要求的题目********
******** * @return 题目字符串********
******** /*******
******** private static String generateValidQuestion() {********
******** while (true) {********
******** int num1 = random.nextInt(100) + 1;********
******** int num2 = random.nextInt(100) + 1;********
******** char operator = getRandomOperator();********
******** // 检查是否符合要求********
******** if (isValidQuestion(num1, num2, operator)) {********
******** return num1 + " " + operator + " " + num2 + " = ";********
******** }********
******** }********
******** }********
******** /**********
******** * 检查题目是否有效********
******** /*******
******** private static boolean isValidQuestion(int num1, int num2, char operator) {********
******** switch (operator) {********
******** case '-'😗*******
******** return num1 >= num2; // 减法不能出现负数********
******** case '×'😗*******
******** return num1 * num2 < 10000; // 乘积不能是四位数********
******** case '÷'😗*******
******** return num2 != 0 && num1 % num2 == 0; // 必须整除********
******** default:********
******** return true; // 加法总是有效********
******** }********
******** }********
******** /**********
******** * 计算题目的正确答案********
******** /*******
******** public static int[] calculateAnswers(String[] questions) {********
******** int[] answers = new int[questions.length];********
******** for (int i = 0; i < questions.length; i++) {********
******** String[] parts = questions[i].split(" ");********
******** int num1 = Integer.parseInt(parts[0]);********
******** int num2 = Integer.parseInt(parts[2]);********
******** char operator = parts[1].charAt(0);********
******** answers[i] = calculate(num1, num2, operator);********
******** }********
******** return answers;********
******** }********
******** /**********
******** * 计算单个表达式的结果********
******** /*******
******** private static int calculate(int num1, int num2, char operator) {********
******** switch (operator) {********
******** case '+': return num1 + num2;********
******** case '-': return num1 - num2;********
******** case '×': return num1 * num2;********
******** case '÷': return num1 / num2;********
******** default: return 0;********
******** }********
******** }********
******** /**********
******** * 进行测试********
******** /*******
******** public static int takeTest(String[] questions, int[] correctAnswers, int timeLimit) {********
******** System.out.println("测试开始!剩余时间:" + timeLimit + "秒");********
******** System.out.println("====================");********
******** long startTime = System.currentTimeMillis();********
******** int correctCount = 0;********
******** List
******** for (int i = 0; i < questions.length; i++) {********
******** // 检查是否超时********
******** long elapsedTime = (System.currentTimeMillis() - startTime) / 1000;********
******** if (elapsedTime >= timeLimit) {********
******** System.out.println("\n时间到!未完成的题目视为错误。");********
******** break;********
******** }********
******** System.out.print((i + 1) + ". " + questions[i]);********
******** int userAnswer = scanner.nextInt();********
******** if (userAnswer == correctAnswers[i]) {********
******** correctCount++;********
******** } else {********
******** wrongQuestions.add(i + 1);********
******** }********
******** }********
******** // 显示错题********
******** if (!wrongQuestions.isEmpty()) {********
******** System.out.println("\n错题统计:");********
******** System.out.println("错题编号:" + wrongQuestions);********
******** System.out.println("正确答案参考:");********
******** for (int index : wrongQuestions) {********
******** int i = index - 1;********
******** System.out.println(index + ". " + questions[i] + correctAnswers[i]);********
******** }********
******** }********
******** return correctCount;********
******** }********
******** /**********
******** * 显示测试结果********
******** /*******
******** public static void showResult(int correctCount, int totalCount) {********
******** double accuracy = (double) correctCount / totalCount * 100;********
******** System.out.println("\n测试结束!");********
******** System.out.println("");********
******** System.out.println("总题数:" + totalCount);********
******** System.out.println("答对题数:" + correctCount);********
******** System.out.printf("正确率:%.2f%%\n", accuracy);********
******** System.out.println("");********
******** }********
******** private static char getRandomOperator() {********
******** char[] operators = {'+', '-', '×', '÷'};********
******** return operators[random.nextInt(operators.length)];********
******** }********
}
```
---
四、其他实验性问题
1. 递归与递推对比
递归实现 n!:
```java
public class Factorial {
******** /**********
******** * 递归方式计算阶乘********
******** /*******
******** public static long factorialRecursive(int n) {********
******** if (n == 0 || n == 1) {********
******** return 1;********
******** }********
******** return n * factorialRecursive(n - 1);********
******** }********
******** /**********
******** * 递推方式计算阶乘********
******** /*******
******** public static long factorialIterative(int n) {********
******** long result = 1;********
******** for (int i = 2; i <= n; i++) {********
******** result = i;*******
******** }********
******** return result;********
******** }********
******** public static void main(String[] args) {********
******** int n = 10;********
******** System.out.println(n + "! (递归) = " + factorialRecursive(n));********
******** System.out.println(n + "! (递推) = " + factorialIterative(n));********
******** }********
}
```
对比分析:
· 递归:代码简洁,逻辑清晰,但存在栈溢出风险
· 递推:性能更好,内存占用少,适合大规模计算
2. 大整数与浮点数处理
BigInteger处理大数阶乘:
```java
import java.math.BigInteger;
public class BigNumberFactorial {
******** /**********
******** * 使用BigInteger计算大数阶乘********
******** /*******
******** public static BigInteger factorialBig(int n) {********
******** if (n == 0 || n == 1) {********
******** return BigInteger.ONE;********
******** }********
******** return BigInteger.valueOf(n).multiply(factorialBig(n - 1));********
******** }********
******** /**********
******** * 正确的浮点数比较方法********
******** /*******
******** public static boolean compareDouble(double a, double b) {********
******** return Math.abs(a - b) < 1e-10;********
******** }********
******** public static void main(String[] args) {********
******** // 大数阶乘示例********
******** int n = 100;********
******** System.out.println(n + "! = " + factorialBig(n));********
******** // 浮点数比较示例********
******** double i = 0.0001;********
******** double j = 0.00010000000000000001;********
******** System.out.println("直接比较: " + (i == j)); // false********
******** System.out.println("正确比较: " + compareDouble(i, j)); // true********
******** }********
}
```
---
五、学习心得与代码仓库建立
学习收获
1. 方法设计:理解了方法的重载、参数传递、返回值等核心概念
2. 递归思维:掌握了递归问题的分析和解决方法
3. 问题处理:学会了处理大数字和浮点数精度问题
4. 实践能力:通过四则运算项目提升了综合编程能力
代码仓库建立建议
建立个人代码仓库是提升编程效率的重要方式:
```java
// 示例:简单的代码管理类
public class CodeLibrary {
******** private Map<String, String> codeSnippets = new HashMap<>();********
******** /**********
******** * 添加代码片段********
******** /*******
******** public void addSnippet(String category, String name, String code) {********
******** String key = category + "::" + name;********
******** codeSnippets.put(key, code);********
******** }********
******** /**********
******** * 查找代码片段********
******** /*******
******** public String findSnippet(String category, String name) {********
******** String key = category + "::" + name;********
******** return codeSnippets.get(key);********
******** }********
******** /**********
******** * 显示所有分类********
******** /*******
******** public void showCategories() {********
******** Set
******** for (String key : codeSnippets.keySet()) {********
******** categories.add(key.split(":😊[0]);********
******** }********
******** System.out.println("可用分类: " + categories);********
******** }********
}
```
分类建议:
· math - 数学相关工具方法
· string - 字符串处理方法
· file - 文件操作工具
· algorithm - 常用算法实现
· utils - 通用工具方法
---
六、总结
通过本次课程的学习和实践,我深刻理解了Java方法的核心概念和应用技巧。从简单的方法定义到复杂的递归算法,从基础的四则运算到完整的测试系统实现,每个环节都让我对面向对象编程有了更深的认识。
建立个人代码仓库的习惯将极大提升未来的开发效率,这也是本次课程最重要的收获之一。********
浙公网安备 33010602011771号