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

【华为机试】HJ68 成绩排序

文章目录

  • HJ68 成绩排序
    • 描述
    • 输入描述
    • 输出描述
    • 示例1
    • 示例2
    • 解题思路
      • 算法分析
      • 数据结构设计
      • 稳定排序原理
      • 排序逻辑详解
      • 比较函数设计
      • 算法流程图
      • 代码实现思路
      • 时间复杂度分析
      • 关键优化点
      • 边界情况处理
      • 测试用例分析
      • 算法特点
      • 实际应用场景
      • 稳定排序的重要性
    • 完整题解代码

HJ68 成绩排序

描述

对于给出的 n 条姓名和成绩信息,根据指定的排序方式按成绩升序或降序排列并输出。
特别的,成绩相同的同学需要保持输入的先后顺序进行排序。可能存在多条信息的学生姓名一致。

输入描述

第一行输入一个整数 n(1<=n<=200) 代表学生人数。
第二行输入一个整数 op(0<=op<=1) 代表排序方式,其中,0 表示按成绩降序,1 表示按成绩升序。
此后 n 行,第 i 行依次输入:

  • 一个长度为 1<=len(si)<=20、由大小写字母构成的字符串 si 代表第 i 个学生的姓名;
  • 一个整数 ai(0<=ai<=100) 代表这个学生的成绩。

输出描述

根据输入的排序方式,按照成绩升序或降序输出所有学生的姓名和成绩。对于每一名学生,新起一行。输出学生的姓名和成绩,用空格分隔。

示例1

输入:
3
0
fang 90
yang 50
ning 70

输出:
fang 90
ning 70
yang 50

说明:
在这个样例中,op=0,因此按成绩降序排序。

示例2

输入:
4
1
fang 90
yang 50
ning 70
yang 70

输出:
yang 50
ning 70
yang 70
fang 90

说明:
在这个样例中,op=1,因此按成绩升序排序。

解题思路

算法分析

这道题的核心是稳定排序学生信息管理。主要涉及:

  1. 数据结构设计:学生信息的存储和排序
  2. 稳定排序算法:保持相同成绩学生的原始顺序
  3. 排序条件控制:根据op参数决定升序或降序
  4. 多关键字排序:成绩为主键,输入顺序为辅助键

数据结构设计

contains
Student
+string Name
+int Score
+int Index
+String() : string
StudentList
+[]Student students
+int sortOrder
+Add(name, score, index)
+Sort()
+Display()

稳定排序原理

学生成绩列表
按成绩排序
成绩相同?
保持原始顺序
按成绩排序
稳定排序结果
排序策略
主键: 成绩
辅助键: 输入顺序
升序/降序
始终升序
最终排序结果

排序逻辑详解

0
1
输入学生信息
创建学生结构体
记录输入顺序
添加到学生列表
读取完所有学生?
执行稳定排序
排序方式op
按成绩降序
按成绩升序
自定义比较函数
稳定排序算法
输出排序结果

比较函数设计

升序
降序
比较函数
成绩是否相等?
按输入顺序排序
排序方式
成绩小的在前
成绩大的在前
保持稳定性
排序结果

算法流程图

op=0
op=1
读取学生数量n
读取排序方式op
初始化学生列表
循环读取学生信息
解析姓名和成绩
创建学生对象
记录输入顺序
添加到列表
是否读取完毕?
执行稳定排序
排序方式判断
降序排序
升序排序
自定义比较函数
sort.SliceStable执行
输出排序结果

代码实现思路

  1. 学生结构体

    • 包含姓名、成绩、输入顺序
    • 提供清晰的数据封装
    • 支持字符串输出格式
  2. 稳定排序实现

    • 使用Go的sort.SliceStable函数
    • 自定义比较函数处理排序逻辑
    • 确保相同成绩的学生保持原始顺序
  3. 排序策略

    • 主键:成绩(按op参数升序或降序)
    • 辅助键:输入顺序(始终升序,保证稳定性)
    • 多关键字排序确保结果正确

时间复杂度分析

  • 时间复杂度:O(n log n),其中n是学生数量
  • 空间复杂度:O(n),存储学生信息

关键优化点

  1. 稳定排序:使用sort.SliceStable保证稳定性
  2. 输入顺序记录:为每个学生记录输入顺序
  3. 比较函数优化:先比较成绩,再比较输入顺序
  4. 内存管理:使用切片高效管理学生列表

边界情况处理

  1. 成绩相同:按输入顺序排列
  2. 姓名相同:按成绩和输入顺序排列
  3. 单个学生:直接输出
  4. 极端成绩:0分和100分的正确处理

测试用例分析

示例1: 3学生降序
fang 90, yang 50, ning 70
排序后: fang 90, ning 70, yang 50
稳定性测试
相同成绩学生
保持输入顺序
边界测试
单个学生
成绩相同
姓名相同
验证排序正确

算法特点

  1. 稳定排序:保证相同成绩学生的相对位置
  2. 灵活排序:支持升序和降序两种模式
  3. 高效实现:使用标准库的稳定排序算法
  4. 易于扩展:可以轻松添加更多排序关键字

实际应用场景

  1. 学生成绩管理:学校成绩排名系统
  2. 考试排序:各类考试成绩排序
  3. 竞赛排名:保持并列名次的相对顺序
  4. 数据分析:需要稳定排序的数据处理

稳定排序的重要性

稳定排序特点
保持相对顺序
多关键字排序
公平性保证
相同成绩学生
成绩优先输入顺序次之
先到先得原则
实际应用价值

这个问题的关键在于正确理解稳定排序的含义设计合理的比较函数,确保在成绩相同的情况下保持学生的原始输入顺序。

完整题解代码

package mainimport ("fmt""sort"
)// Student 学生结构体
type Student struct {Name  string // 学生姓名Score int    // 学生成绩Index int    // 输入顺序,用于稳定排序
}// StudentList 学生列表管理
type StudentList struct {Students  []Student // 学生列表SortOrder int       // 排序方式:0-降序,1-升序
}// Add 添加学生
func (sl *StudentList) Add(name string, score int, index int) {student := Student{Name:  name,Score: score,Index: index,}sl.Students = append(sl.Students, student)
}// Sort 执行稳定排序
func (sl *StudentList) Sort() {sort.SliceStable(sl.Students, func(i, j int) bool {// 如果成绩相同,按输入顺序排序(保持稳定性)if sl.Students[i].Score == sl.Students[j].Score {return sl.Students[i].Index < sl.Students[j].Index}// 根据排序方式决定升序或降序if sl.SortOrder == 0 {// 降序:成绩大的在前return sl.Students[i].Score > sl.Students[j].Score} else {// 升序:成绩小的在前return sl.Students[i].Score < sl.Students[j].Score}})
}// Display 输出排序结果
func (sl *StudentList) Display() {for _, student := range sl.Students {fmt.Printf("%s %d\n", student.Name, student.Score)}
}func main() {var n, op int// 读取学生数量和排序方式fmt.Scan(&n)fmt.Scan(&op)// 创建学生列表studentList := StudentList{Students:  make([]Student, 0, n),SortOrder: op,}// 读取学生信息for i := 0; i < n; i++ {var name stringvar score intfmt.Scan(&name, &score)// 添加学生,记录输入顺序studentList.Add(name, score, i)}// 执行稳定排序studentList.Sort()// 输出排序结果studentList.Display()
}
http://www.dtcms.com/a/276437.html

相关文章:

  • 从0设计一个短链接服务:如何实现尽可能短、可变长的短网址系统?
  • 过拟合 跷跷板 幻觉 混合精度
  • 计算机毕业设计springboot影视周边推荐系统 基于SpringBoot的电影衍生品智能推荐平台 JavaWeb实现的影视文化周边个性化服务系统
  • git版本发布
  • 黑客工具Nessus介绍及其安装使用教程
  • 使用Kali Linux hydra进行密码爆破(仅供学习)
  • 质量属性场景(Quality Attribute Scenario)深度解析
  • mybatis模糊匹配采用concat与#{},动态sql讲解
  • 模拟专家协作网络——重塑LLM专业内容生成
  • C语言基础知识--枚举
  • 商业智能(BI)系统深度解析
  • Matlab R2024b下载及详细安装教程,附中文免费Matlab安装包(含离线帮助文档)
  • 为什么一个 @Transactional 注解就能开启事务?揭秘 Spring AOP 的底层魔法
  • 维基艺术图片: python + scrapy 爬取图片
  • 【读书笔记】《C++ Software Design》第一章《The Art of Software Design》
  • 典型的前后端交互数据示例
  • 消息认证码(message authentication code)MAC
  • 自动编码器:深度学习的特征提取与数据压缩利器
  • c++11——移动语义的举例说明
  • 数据结构与算法:逆元、除法同余和容斥原理
  • 指令微调时,也要考虑提示损失
  • Linux - 安全排查 3
  • 用 MATLAB 模拟传染病传播:从 SI 模型到 SIS 模型的可视化之旅
  • 【无标题】基于拓扑膨胀-收缩对偶性(TED),TED原理构建任意维度TQCD模型并推演宇宙可能性的完整方案:
  • 网络连接:拨号连接宽带PPPOE
  • 数据库索引创建与使用详细笔记
  • Linux的NetworkManager的nmcli配置网桥(bridge) 笔记250712
  • 【6.1.1 漫画分库分表】
  • 挖矿病毒判断与处理 - 入门
  • 26-计组-寻址方式