news 2026/7/1 23:05:30

结构体(Java 类)实战题解笔记(持续更新)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
结构体(Java 类)实战题解笔记(持续更新)

前言

Java也可以有结构体吗?
在 Java 中并没有直接的「结构体」概念,但可以通过自定义类(class)实现结构体的核心功能——封装一组具有关联关系的数据。本笔记通过实战题目,讲解如何用自定义类存储复杂数据、处理业务逻辑,后续可直接沿用该笔记格式补充更多同类题目。

题目1:歌唱比赛得分统计(求最高平均分)

题目核心需求

统计 n 名同学的歌唱比赛得分,每位同学有 m 名评委打分,得分规则为「去掉一个最高分、一个最低分后求平均值」,最终输出所有同学中的最高平均分(保留 2 位小数)。

解题思路

  1. 封装数据模型:定义Student类,封装每位同学的评委分数数组、最高分、最低分、总分(去高低分后)、平均分。
  2. 初始化数据:创建 n 个Student实例,每个实例初始化对应长度的评委分数数组。
  3. 读取并计算数据:逐行读取评委打分,同时计算该同学的最高分、最低分、原始总分;后续扣除高低分,计算有效平均分。
  4. 排序找最大值:通过冒泡排序对所有同学的平均分进行升序排列,排序后最后一个元素即为最高平均分。
  5. 格式化输出:保留 2 位小数输出结果。

核心代码解析

packageStruct;importjava.util.Scanner;// 封装学生歌唱比赛数据的类(对应结构体功能)classStudent{intid;// 可选:学生编号,本题未要求使用inta[];// 存储m名评委的打分intmax=-1;// 最高分,初始值低于最小可能得分(0)intmin=11;// 最低分,初始值高于最大可能得分(10)doubleavg;// 有效平均分(去高低分后)doublesum;// 原始总分(所有评委打分之和)}publicclassMain{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);intn=sc.nextInt();// 学生人数intm=sc.nextInt();// 评委人数Studentsts[]=newStudent[n];// 学生数组,存储所有学生信息// 步骤1:初始化学生数组和每个学生的分数数组for(inti=0;i<n;i++){sts[i]=newStudent();// 必须实例化每个Student,否则会出现空指针异常sts[i].a=newint[m];// 初始化每个学生的评委分数数组}// 步骤2:读取打分并计算每个学生的核心数据(max、min、sum、avg)for(inti=0;i<n;i++){for(intj=0;j<m;j++){sts[i].a[j]=sc.nextInt();// 读取单个评委打分sts[i].sum+=sts[i].a[j];// 累加原始总分// 更新最高分和最低分sts[i].max=Math.max(sts[i].a[j],sts[i].max);sts[i].min=Math.min(sts[i].a[j],sts[i].min);}// 计算有效总分(去掉最高分和最低分)sts[i].sum-=(sts[i].max+sts[i].min);// 计算有效平均分,*1.0 确保除法结果为小数,避免整数除法丢失精度sts[i].avg=sts[i].sum*1.0/(m-2);}// 步骤3:冒泡排序(升序),将平均分最低的放前面,最高的放后面for(inti=0;i<n-1;i++){for(intj=0;j<n-1-i;j++){if(sts[j].avg>sts[j+1].avg){// 交换两个学生对象(整体交换,无需单独交换每个字段,体现类封装的优势)Studenttemp=sts[j];sts[j]=sts[j+1];sts[j+1]=temp;}}}// 步骤4:格式化输出最高平均分(保留2位小数)System.out.printf("%.2f\n",sts[n-1].avg);sc.close();}}
关键注意点
  1. 数组初始化Student sts[] = new Student[n]仅创建了数组容器,每个数组元素(Student对象)需要单独new Student()实例化,否则会抛出NullPointerException
  2. 数据类型精度:计算平均分时分母是m-2(整数),需要通过*1.0将分子转为浮点型,避免整数除法(直接舍弃小数部分)导致结果错误。
  3. 极值初始化:最高分max初始化为-1(低于最小可能得分 0),最低分min初始化为11(高于最大可能得分 10),确保能被评委打分正确覆盖。

输入输出示例

输入:

7 6 4 7 2 6 10 7 0 5 0 10 3 10 2 6 8 4 3 6 6 3 6 7 5 8 5 9 3 3 8 1 5 9 9 3 2 0 5 8 0 4 1 10

输出:

6.00

题目2:期末考试「旗鼓相当的对手」匹配

题目核心需求

给定 N 名同学的姓名和语、数、英成绩,找出所有「旗鼓相当的对手」组合:

  1. 每科成绩分差均不大于 5;
  2. 总分分差均不大于 10;
  3. 输出时满足字典序:第一个姓名字典序 < 第二个姓名,且组合整体按字典序排序。

解题思路

  1. 封装数据模型:定义Student2类,封装同学的姓名、三科成绩、总分。
  2. 读取并存储数据:读取 N 名同学的信息,实例化Student2对象并存入数组(输入已按字典序排列,数组天然保留该顺序)。
  3. 双重循环匹配组合:使用两层循环遍历所有i < j的同学组合(避免重复组合,且保证i在前j在后,符合字典序要求)。
  4. 判断对手条件:逐一验证三科分差和总分分差的条件,满足则输出对应姓名组合。
  5. 保证输出格式:因输入已按字典序排列,i < j的循环组合直接输出即可满足题目字典序要求。

核心代码解析

packageStruct;importjava.util.Scanner;// 封装学生期末考试数据的类(对应结构体功能)classStudent2{Stringname;// 学生姓名intchinese;// 语文成绩intmath;// 数学成绩intenglish;// 英语成绩intsum;// 三科总分}publicclassMain2{publicstaticvoidmain(String[]args){Scannersc=newScanner(System.in);intn=sc.nextInt();// 学生人数Student2sts[]=newStudent2[n];// 学生数组,存储所有学生信息// 步骤1:读取并初始化所有学生的信息for(inti=0;i<n;i++){sts[i]=newStudent2();// 实例化每个Student2对象,避免空指针异常// 处理换行符问题:nextInt()后未读取换行符,next()会自动跳过空白字符(包括换行、空格),此处可省略sc.nextLine()sts[i].name=sc.next();// 读取姓名(无空格,用next())sts[i].chinese=sc.nextInt();// 读取语文成绩sts[i].math=sc.nextInt();// 读取数学成绩sts[i].english=sc.nextInt();// 读取英语成绩sts[i].sum=sts[i].chinese+sts[i].math+sts[i].english;// 计算总分}// 步骤2:双重循环匹配「旗鼓相当的对手」(i < j 避免重复组合,且符合字典序)for(inti=0;i<n;i++){for(intj=i+1;j<n;j++){// 条件1:每科成绩分差不大于5booleanchineseOk=Math.abs(sts[i].chinese-sts[j].chinese)<=5;booleanmathOk=Math.abs(sts[i].math-sts[j].math)<=5;booleanenglishOk=Math.abs(sts[i].english-sts[j].english)<=5;// 条件2:总分分差不大于10booleansumOk=Math.abs(sts[i].sum-sts[j].sum)<=10;// 满足所有条件,输出组合if(chineseOk&&mathOk&&englishOk&&sumOk){System.out.println(sts[i].name+" "+sts[j].name);}}}sc.close();}}
关键注意点
  1. 避免重复组合:使用i < j的循环逻辑(外层i从 0 到 n-1,内层ji+1到 n-1),既不会出现<i,i>自身组合,也不会出现<j,i><i,j>重复的组合。
  2. 字典序保证:题目明确输入姓名按字典序排列,数组存储顺序与输入顺序一致,i < j对应的sts[i].name字典序必然小于sts[j].name,直接输出即可满足题目要求。
  3. 输入读取技巧:读取姓名使用sc.next()(适用于无空格的字符串),nextInt()next()会自动跳过空白字符(换行、空格),无需额外处理换行符问题(原代码中的if(i==0) sc.nextLine()是冗余的,可删除)。
  4. 分差计算:使用Math.abs()计算绝对值差,避免分差为负数导致判断条件错误。

输入输出示例

输入:

3 fafa 90 90 90 lxl 95 85 90 senpai 100 80 91

输出:

fafa lxl lxl senpai

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/1 21:19:41

Java SpringBoot+Vue3+MyBatis 经方药食两用服务平台系统源码|前后端分离+MySQL数据库

系统架构设计### 摘要 随着中医药文化的普及和健康意识的增强&#xff0c;经方药食两用服务逐渐成为人们关注的焦点。传统的中医药服务模式存在信息分散、查询不便、个性化推荐不足等问题&#xff0c;亟需通过信息化手段提升服务效率和质量。本系统旨在构建一个基于现代技术的经…

作者头像 李华
网站建设 2026/7/1 8:59:36

Spring Boot与微服务核心技术面试实战解析

Spring Boot与微服务核心技术面试实战解析 场景设定&#xff1a; 谢飞机是一名初入职场的Java程序员&#xff0c;正在参加某互联网大厂的面试&#xff0c;面试官是一位严肃且专业的技术专家。 第一轮&#xff1a;Spring Boot基础与项目构建 **面试官&#xff08;严肃脸&…

作者头像 李华
网站建设 2026/6/30 15:04:40

2601,写个kde语法高亮文件

提示:如果想写一个高亮语法文件,XMLCompletion插件可能会很有帮助. 这里概述了KDE4中高亮定义XML格式.基于如下,它将描述主要组成部分及其含义和用法. Kate高亮定义文件的主要部分 在language.dtd文件中也就是DTD,保存正式定义,应该在你的系统目录安装,即$KDEDIR/share/apps/ka…

作者头像 李华
网站建设 2026/7/1 21:21:09

2601C++,复制超文本格式

超文本的剪切板格式 超文本有自己的剪切板格式(叫超文本格式(CF_HTML),可用来向其他应用助手(如Excel,Word或其他办公应用复制)提供数据. CF_HTML是包含说明,环境和该环境中的片段完全基于文本的格式.生成要发送到剪切板的数据时,必须包含数据说明,以指示剪切板版本及环境和片…

作者头像 李华
网站建设 2026/7/1 16:20:38

OTG数据充电交互讲解

随着科技的飞速发展&#xff0c;智能移动设备已成为我们生活中不可或缺的一部分。而在这些设备的连接与数据传输中&#xff0c;Type-C接口以其高效、便捷的特性逐渐占据了主导地位。OTG&#xff08;On-The-Go&#xff09;技术则进一步扩展了Type-C接口的功能&#xff0c;使得设…

作者头像 李华