当前位置: 首页 > news >正文

JAVA实验课程第五次作业分析与代码示例

1.作业内容

1.1 数组中唯一的数字

给定一个整数数组,其中除了某个元素只出现一次外,其余每个元素均出现两次。请找出那个只出现一次的元素。

1.2 验证回文串

编写一个方法,判断一个字符串是否为回文串。回文串是指正读和反读都相同的字符串,忽略字母大小写和非字母数字字符(字母和数字为有效字符)。
示例:输入:"A man, a plan, a canal: Panama"输出:true(忽略非字符后为 “amanaplanacanalpanama”,正反读相同)
输入:"race a car"输出:false

1.3字符串压缩

要求:实现一个字符串压缩算法:将连续重复的字符替换为 “字符 + 重复次数”。如果压缩后的字符串长度不小于原字符串,则返回原字符串。
示例:输入:"aabcccccaaa"输出:"a2b1c5a3"输入:"abc"输出:“abc” 解释:压缩后为 “a1b1c1”,长度更长。

1.4二维数组的转置

编写一个 Java 程序,实现二维整数数组的转置操作。转置是指将原数组的行变为列、列变为行(即原数组中位于(i,j)位置的元素,转置后位于(j,i)位置)。
注意:原数组可能不是方阵(行数和列数可以不同),转置后新数组的行数等于原数组的列数,新数组的列数等于原数组的行数。

1.5数组元素移动

编写一个 Java 程序,将整数数组中所有的 0 元素移动到数组末尾,同时保持非 0 元素的相对顺序不变。不能创建新的数组,必须在原数组上操作。

1.6数字反转与回文判断

编写程序完成两个
任务:
将一个整数反转(如 123→321,-456→-654,1200→21);
判断反转后的数字是否为回文数(即反转前后数字相同,如 121 反转后还是 121,是回文数;123 反转后是 321,不是回文数,-12321也是回文数)。

1.7 中秋国庆双节礼品分配

题目场景

中秋与国庆双节期间,班级要给同学们分配节日礼品,礼品包含 3 类:月饼礼盒、国旗徽章、中秋灯笼。已知每种礼品的总数量和班级人数,要求按以下规则分配礼品,并统计结果:
先给每位同学每种礼品各分配 1 份(确保每人都有基础礼品);
分配完基础礼品后,若某类礼品还有剩余,则按 “从第 1 位同学到最后 1 位同学” 的顺序,每人再额外分配 1 份,直到该类礼品分完(剩余不足 1 份时停止);
最后输出每位同学获得的各类礼品数量、总礼品数,以及每种礼品的剩余数量。

示例:

输入:
班级人数:5 人
礼品总数:月饼礼盒 10 份、国旗徽章 8 份、中秋灯笼 5 份
分配过程:
基础分配:每人各得 1 份月饼、1 份徽章、1 份灯笼,共消耗 5 份月饼、5 份徽章、5 份灯笼;
剩余礼品:月饼剩 5 份、徽章剩 3 份、灯笼剩 0 份;
额外分配:
月饼:按顺序给 5 人各再分 1 份,刚好分完;
徽章:按顺序给前 3 人各再分 1 份,刚好分完;
灯笼:无剩余,不分配。

2. 题目分析与解答

2.1 数组中唯一的数字

a.计数法

分析:这一道题我们要计算每个元素出现的次数,出现2次代表没问题。因此,我们只需要记录下来我们每一个元素出现的次数即可。


1.使用哈希表(HashMap)记录每个数字出现的次数,最后找出次数为 1 的数字。
2.使用一个数组记录。我们可以初始化一个全为0的数组,比如当2出现一次的时候,我们可以让arr[2]++,最后我们便利数组找出数组中值为1的下标即可。


b.亦或运算

分析:
利用异或运算的特性,相同数字异或结果为 0,0 与任何数字异或结果为该数字本身,遍历数组对所有元素进行异或操作即可得到唯一的数字。

public static void main(String[] args) {int[] nums = {4, 1, 2, 1, 2};System.out.println("数组中唯一的数字是: " + findUniqueNumber(nums));// 可以添加更多测试用例int[] nums2 = {7, 3, 5, 4, 5, 3, 4};System.out.println("另一组测试中唯一的数字是: " + findUniqueNumber(nums2));}// 找出数组中唯一的数字public static int findUniqueNumber(int[] nums) {int result = 0;// 利用异或运算特性:a^a=0,a^0=a,异或满足交换律和结合律for (int num : nums) {result ^= num;}return result;}

2.2 验证回文串

分析:先过滤掉非字母数字字符并转为小写,然后使用双指针从两端向中间比较,判断是否为回文串。

public static void main(String[] args) {String s1 = "A man, a plan, a canal: Panama";String s2 = "race a car";System.out.println("\"" + s1 + "\" 是否为回文串: " + isPalindrome(s1));System.out.println("\"" + s2 + "\" 是否为回文串: " + isPalindrome(s2));}// 验证回文串public static boolean isPalindrome(String s) {// 过滤非字母数字字符并转为小写StringBuilder filtered = new StringBuilder();for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (Character.isLetterOrDigit(c)) {filtered.append(Character.toLowerCase(c));}}// 双指针判断是否回文int left = 0;int right = filtered.length() - 1;while (left < right) {if (filtered.charAt(left) != filtered.charAt(right)) {return false;}left++;right--;}return true;}

2.3 字符串压缩

分析

根据题目意思,可以分为两部分:
-1.遍历字符串统计连续相同字符的个数,构建压缩后的字符串。
-2.最后比较压缩前后的长度,返回较短的那个。

代码

 public static void main(String[] args) {String str1 = "aabcccccaaa";String str2 = "abc";String str3 = "aaaaabbbbbccccc";System.out.println("\"" + str1 + "\" 压缩后: " + compressString(str1));System.out.println("\"" + str2 + "\" 压缩后: " + compressString(str2));System.out.println("\"" + str3 + "\" 压缩后: " + compressString(str3));}// 字符串压缩public static String compressString(String s) {if (s.length() <= 1) {return s;}StringBuilder compressed = new StringBuilder();char current = s.charAt(0);int count = 1;for (int i = 1; i < s.length(); i++) {if (s.charAt(i) == current) {count++;} else {compressed.append(current).append(count);current = s.charAt(i);count = 1;}}// 添加最后一组字符compressed.append(current).append(count);// 如果压缩后长度不小于原长度,返回原字符串return compressed.length() < s.length() ? compressed.toString() : s;}

2.4 二维数组的转置

分析

转置的本质是交换数组的行索引和列索引。例如原数组中matrix[i][j]的元素,在转置后的数组中会位于transposed[j][i]的位置。

代码实现

  • 实现步骤:
    首先确定原数组的行数(rows)和列数(cols);
    创建转置后的新数组,其行数为原数组的列数,列数为原数组的行数;
    通过嵌套循环遍历原数组,将每个元素放入新数组的对应位置;
    提供printMatrix方法用于打印数组,方便观察转置效果。
  • 代码:
public static void main(String[] args) {// 测试用例1:2行3列的数组int[][] matrix1 = {{1, 2, 3},{4, 5, 6}};System.out.println("原数组(2行3列):");printMatrix(matrix1);int[][] transposed1 = transpose(matrix1);System.out.println("转置后(3行2列):");printMatrix(transposed1);// 测试用例2:3行3列的方阵int[][] matrix2 = {{10, 20, 30},{40, 50, 60},{70, 80, 90}};System.out.println("\n原数组(3行3列):");printMatrix(matrix2);int[][] transposed2 = transpose(matrix2);System.out.println("转置后(3行3列):");printMatrix(transposed2);// 测试用例3:1行5列的数组int[][] matrix3 = {{1, 2, 3, 4, 5}};System.out.println("\n原数组(1行5列):");printMatrix(matrix3);int[][] transposed3 = transpose(matrix3);System.out.println("转置后(5行1列):");printMatrix(transposed3);}// 二维数组转置的核心方法public static int[][] transpose(int[][] matrix) {// 原数组的行数和列数int rows = matrix.length;// 若原数组为空,直接返回空数组if (rows == 0) {return new int[0][0];}int cols = matrix[0].length;// 创建转置后的新数组:行数=原列数,列数=原行数int[][] transposed = new int[cols][rows];// 遍历原数组,填充转置后的数组for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {// 原数组(i,j)位置的元素 → 转置后(j,i)位置transposed[j][i] = matrix[i][j];}}return transposed;}// 辅助方法:打印二维数组public static void printMatrix(int[][] matrix) {for (int i = 0; i < matrix.length; i++) {System.out.print("[ ");for (int j = 0; j < matrix[i].length; j++) {System.out.print(matrix[i][j] + " ");}System.out.println("]");}}

2.5 数组元素移动

分析:
分两步操作,首先将所有非 0 元素移到前面,然后将剩余位置填充 0,确保在原数组上操作。

public static void main(String[] args) {int[] arr1 = {0, 1, 0, 3, 12};int[] arr2 = {0, 0, 1};int[] arr3 = {1, 2, 3};System.out.print("原数组1: ");printArray(arr1);moveZeros(arr1);System.out.print("移动0之后: ");printArray(arr1);System.out.print("\n原数组2: ");printArray(arr2);moveZeros(arr2);System.out.print("移动0之后: ");printArray(arr2);System.out.print("\n原数组3: ");printArray(arr3);moveZeros(arr3);System.out.print("移动0之后: ");printArray(arr3);}// 打印数组public static void printArray(int[] arr) {for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]);if (i < arr.length - 1) {System.out.print(", ");}}System.out.println();}// 数组元素移动:将所有0移到末尾public static void moveZeros(int[] nums) {int nonZeroIndex = 0;// 把所有非0元素移到前面for (int i = 0; i < nums.length; i++) {if (nums[i] != 0) {nums[nonZeroIndex] = nums[i];nonZeroIndex++;}}// 剩余位置填充0for (int i = nonZeroIndex; i < nums.length; i++) {nums[i] = 0;}}

2.6 数字反转与回文判断

分析:

处理负数情况,通过取余和乘 10 操作反转数字,最后比较原数字和反转后的数字是否相等来判断是否为回文数。

思考:是否可以使用第二题中的方式?为何不使用第二题中的方式?

代码解析:

public static void main(String[] args) {int num1 = 12321;int num2 = -123;int num3 = 1200;int num4 = -12321;reverseAndCheckPalindrome(num1);reverseAndCheckPalindrome(num2);reverseAndCheckPalindrome(num3);reverseAndCheckPalindrome(num4);}// 数字反转与回文判断public static void reverseAndCheckPalindrome(int num) {int original = num;int reversed = 0;boolean isNegative = num < 0;// 处理负数if (isNegative) {num = -num;}// 反转数字while (num != 0) {int digit = num % 10;reversed = reversed * 10 + digit;num /= 10;}// 恢复负数if (isNegative) {reversed = -reversed;}// 判断是否为回文数boolean isPalindrome = original == reversed;System.out.println(original + " 反转后: " + reversed + "," + (isPalindrome ? "是回文数" : "不是回文数"));}

2.7 中秋国庆双节礼品分配

输出示例:

在这里插入图片描述

代码实现

public class FestivalGiftAllocator {public static void main(String[] args) {// 1. 定义节日相关数据:礼品名称、总数量,班级人数String[] giftNames = {"月饼礼盒", "国旗徽章", "中秋灯笼"}; // 双节礼品类型int[] totalGifts = {10, 8, 5}; // 每种礼品的总数量(对应上面的礼品顺序)int studentCount = 5; // 班级人数// 2. 创建数组存储每位同学的礼品数量:studentGifts[同学索引][礼品类型索引]int[][] studentGifts = new int[studentCount][giftNames.length];// 创建数组存储每种礼品的剩余数量int[] remainingGifts = new int[giftNames.length];// 3. 第一步:基础分配(每人每种礼品各1份)for (int i = 0; i < giftNames.length; i++) {// 若该类礼品总数 >= 人数,才能给每人分1份;否则无法完成基础分配(题目默认总礼品足够基础分配)if (totalGifts[i] >= studentCount) {for (int j = 0; j < studentCount; j++) {studentGifts[j][i] = 1; // 每人该礼品分1份}// 计算基础分配后的剩余数量remainingGifts[i] = totalGifts[i] - studentCount;}}// 4. 第二步:额外分配(剩余礼品按顺序分给同学,每人每次1份)for (int i = 0; i < giftNames.length; i++) {// 若该类礼品有剩余,才进行额外分配if (remainingGifts[i] > 0) {int giftLeft = remainingGifts[i]; // 当前剩余的礼品数int studentIndex = 0; // 从第1位同学开始(索引0)// 循环分配,直到礼品分完或所有同学都额外分过while (giftLeft > 0 && studentIndex < studentCount) {studentGifts[studentIndex][i] += 1; // 给当前同学额外分1份giftLeft -= 1; // 剩余礼品减1studentIndex += 1; // 下一位同学}// 更新剩余礼品数(此时giftLeft应为0,除非礼品没分完,但题目默认可分完)remainingGifts[i] = giftLeft;}}// 5. 输出每位同学的礼品分配结果for (int i = 0; i < studentCount; i++) {int total = 0; // 统计当前同学的总礼品数// 拼接该同学的各类礼品信息StringBuilder giftInfo = new StringBuilder();for (int j = 0; j < giftNames.length; j++) {giftInfo.append(giftNames[j]).append(studentGifts[i][j]).append("份");if (j < giftNames.length - 1) {giftInfo.append(",");}total += studentGifts[i][j]; // 累加总礼品数}// 输出结果(注意:同学编号从1开始,索引从0开始,所以+1)System.out.println("第" + (i + 1) + "位同学:" + giftInfo + ",总礼品数" + total + "份");}// 6. 输出剩余礼品System.out.println("\n剩余礼品:");for (int i = 0; i < giftNames.length; i++) {System.out.println(giftNames[i] + ":" + remainingGifts[i] + "份");}}
}
http://www.dtcms.com/a/450015.html

相关文章:

  • 龙口网站制作公司深圳知名设计公司有哪些
  • 网站数据修改网页界面设计的起源
  • 东莞建设网站官网住房和城乡wordpress 如何修改like和dislike
  • Gopher二次编码原因解析
  • 【ARM汇编语言基础】-数据处理指令(七)
  • 汇编与反汇编
  • 福州建设网站shopee怎么注册开店
  • 建立网站站点的目的贵州二级站seo整站优化排名
  • 阳江做网站多少钱企业网站推广方法有哪些
  • sm2025 模拟赛11 (2025.10.5)
  • python镜像源配置
  • 4.寻找两个正序数组的中位数-二分查找
  • 理解CC++异步IO编程:Epoll入门
  • wordpress房屋网站模板微信小程序
  • 阿里网站建设视频教程WordPress云媒体库
  • SpringCloud 入门 - Nacos 配置中心
  • Windows 下使用 Claude Code CLI 启动 Kimi
  • 网站推广的基本方式抖音特效开放平台官网
  • 湖南网站排名wordpress插件seo
  • WindowsKyLin:nginx安装与配置
  • 【剑斩OFFER】算法的暴力美学——最大连续1的个数 III
  • UNIX下C语言编程与实践32-UNIX 僵死进程:成因、危害与检测方法
  • 论坛开源网站源码首页优化排名
  • 网站建设策请seo的人帮做网站排名
  • 旅游网站后台html模板做网站的做app的
  • 网站备案回访问题效果好的网站制作
  • Unity 光源
  • 应急响应
  • 【2061】梯形面积
  • 电商网站seo优化目标分解wordpress域名授权