华为OD机试真题---磁盘容量排序

news/2024/10/28 17:26:53/

华为OD机试中的“磁盘容量排序”题目是一道考察应聘者编程能力和算法理解的经典题目。以下是对这道题目的详细解析:

一、题目描述

磁盘的容量单位常用的有M,G,T这三个等级,它们之间的换算关系为1T=1024G,1G=1024M,现在给定n块磁盘的容量,请对它们按从小到大的顺序进行稳定排序只,例如给定5块盘的容量,1T,20M,3G,10G6T,3M12G9M排序后的结果为20M,3G,3M12G9M,1T,10G6T。注意单位可以重复出现,上述3M12G9M表示的容量即为3M+12G+9M,和12M12G相等。

二、输入描述

  • 输入第一行包含一个整数n(2<=n<= 100),表示磁盘的个数。
  • 接下的n行,每行一个字符串(长度大于2,小于30),表示磁盘的容量,由一个或多个格式为mv的子串组成,其中m表示容量大小,v表示容量单位,例如20M,1T,30G,10G6T,3M12G9M。
  • 磁盘容量m的范围为1到1024的正整数,容量单位v的范围只包含题目中提到的M,G,T三种,换算关系如题目描述。

三、输出描述

输出n行,表示n块磁盘容量排序后的结果。

四、解题思路

  1. 解析输入

    • 首先读取输入的整数n,它表示磁盘的个数。
    • 接着读取接下来的n行,每行包含一个表示磁盘容量的字符串。
  2. 解析容量字符串

    • 对于每个容量字符串,我们需要将其拆分为多个mv子串,其中m是容量大小,v是容量单位。
    • 将每个子串的容量大小乘以对应的单位换算系数(M=1, G=1024, T=1024^2),然后将所有结果相加,得到该磁盘的总容量(以M为单位)。
  3. 存储和排序

    • 使用一个列表来存储每个磁盘的原始字符串和计算出的总容量(以M为单位)。
    • 使用Java的Collections.sort方法对列表进行排序,排序时根据总容量进行比较,但保留原始字符串以便输出。
  4. 输出排序结果

    • 按照排序后的顺序输出每个磁盘的原始容量字符串。

五、代码实现

java">import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;/*** 磁盘容量解析和排序工具类*/
class DiskCapacity {// 换算系数private static final int M = 1; // 兆字节private static final int G = 1024; // 吉字节private static final int T = 1024 * 1024; // 太字节/*** 解析容量字符串并返回总容量(以兆字节为单位)* 支持的单位有:M(兆字节)、G(吉字节)、T(太字节)* @param capacityStr 容量字符串* @return 总容量(以兆字节为单位)* @throws NumberFormatException 如果输入字符串格式不正确*/private static int parseCapacity(String capacityStr) {int totalCapacityInM = 0;// 根据单位和数字边界分割字符串String[] parts = capacityStr.split("(?<=[MGT])\\s*");for (String part : parts) {// 跳过空字符串if (part.isEmpty()) continue;// 提取数字部分int size = Integer.parseInt(part.substring(0, part.length() - 1));// 提取单位部分char unit = part.charAt(part.length() - 1);switch (unit) {case 'M':totalCapacityInM += size * M;break;case 'G':totalCapacityInM += size * G;break;case 'T':totalCapacityInM += size * T;break;default:throw new NumberFormatException("未知的单位: " + unit);}}return totalCapacityInM;}/*** 主函数用于读取用户输入的磁盘容量字符串,解析并按容量排序后输出* @param args 命令行参数,未使用*/public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();scanner.nextLine(); // 消耗掉换行符// 创建一个列表用于存储容量信息及其原始字符串表示List<Map.Entry<Integer, String>> capacities = new ArrayList<>();// 遍历输入,读取n次以收集所有容量信息for (int i = 0; i < n; i++) {// 读取下一行输入作为容量的字符串表示String capacityStr = scanner.nextLine();try {// 解析容量字符串为整数,表示总容量(以M为单位)int totalCapacityInM = parseCapacity(capacityStr);// 将解析后的容量及其原始字符串添加到列表中capacities.add(new AbstractMap.SimpleEntry<>(totalCapacityInM, capacityStr));} catch (NumberFormatException e) {// 处理解析错误,打印无效输入的错误信息System.err.println("无效的输入: " + capacityStr + ", 错误: " + e.getMessage());}}// 使用稳定排序(例如TimSort,Java的Arrays.sort和Collections.sort都使用它)capacities.sort(Map.Entry.comparingByKey());// 输出排序后的结果for (Map.Entry<Integer, String> entry : capacities) {System.out.println(entry.getValue());}scanner.close();}
}

六、运行示例解析

输入

5
1T
20M
3G
10G6T
3M12G9M

解析

  1. 1T 解析为 1 * 1024^2 = 1048576M
  2. 20M 解析为 20 * 1 = 20M
  3. 3G 解析为 3 * 1024 = 3072M
  4. 10G6T 解析为 (10 * 1024) + (6 * 1024^2) = 6291440 + 6291456 = 12582896M
  5. 3M12G9M 解析为 (3 * 1) + (12 * 1024) + (9 * 1) = 3 + 12288 + 9 = 12297 + 3 = 12300M(注意这里我们合并了所有的M、G单位)

排序

  • 按总容量(以M为单位)排序:20M, 3072M (3G), 12300M (3M12G9M), 1048576M (1T), 12582896M (10G6T)

输出

20M
3G
3M12G9M
1T
10G6T

这个输出与题目要求的稳定排序结果一致。注意,在解析3M12G9M时,我们将其视为3M + 12G + 9M,并正确地将所有单位转换为M以进行比较。

七、扩展与注意事项
  1. 输入验证

    • 在实际应用中,应增加对输入的验证,如检查输入字符串是否符合格式要求,是否包含非法字符等。
    • 可以使用正则表达式或字符串处理方法进行验证。
  2. 异常处理

    • 在解析容量字符串时,应捕获并处理可能的异常,如NumberFormatException等。
    • 在主函数中,应捕获并处理可能发生的异常,以确保程序的健壮性。
  3. 性能优化

    • 如果输入的磁盘数量非常大,可以考虑使用更高效的排序算法数据结构来优化性能。
    • 在解析容量字符串时,可以使用更高效的字符串分割方法或正则表达式匹配技术来提高解析速度。
  4. 代码可读性

    • 在编写代码时,应注重代码的可读性和可维护性。
    • 可以使用注释、变量命名和代码结构等方式来提高代码的可读性。
  5. 扩展性

    • 如果需要支持更多的容量单位或更复杂的容量表示方式(如小数表示、科学计数法等),可以对parseCapacity方法进行扩展和修改。
    • 可以将解析和排序功能封装为独立的类或方法,以便在其他项目中复用。
  6. 正则表达式的应用

  • 一定要注意正则表达式的应用否则String[] parts = capacityStr.split("(?<=[MGT])\\s*");这里应用不对,很容易出错。

http://www.ppmy.cn/news/1542643.html

相关文章

【js逆向专题】12.RPC技术

目录 一. websocket1. 什么是websocket2. websocket的原理3. websocket实现方式1. 客户端2.服务端3. 实际案例1. 案例目标2. 解析思路 二. RPC1. RPC 简介2.Sekiro-RPC1. 使用方法1. 执行方式2.客户端环境3.使用参数说明 2. 测试使用1. 前端代码2. SK API3.python调用代码 三.项…

matlab逻辑与有两种表达

在 MATLAB 中&#xff0c;要判断一个数值是否同时满足小于等于 44 和大于等于 15&#xff0c;你可以使用逻辑与运算符 &&&#xff08;在 if 语句中&#xff09;或 &&#xff08;在数组逻辑运算中&#xff09;。以下是如何在 if 语句中进行这种判断的例子&#xff1…

攻防世界的新手web题解

攻防世界引导模式 1、disabled_button 好&#xff0c;给了一个按钮&#xff0c;第一道题目就不会做 看的wp<input disabled class"btn btn-default" style"height:50px;width:200px;" type"submit" value"flag" name"auth&q…

Python中的Pyqt5详细介绍:基本机构、部件、布局管理、信号与槽、跨平台

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

字节面试:如何测试RocketMQ、RocketMQ?测试点有哪些?

字节面试&#xff1a;RocketMQ是怎么测试的呢&#xff1f; 答&#xff1a; 首先保证消息的消费正确、设计逆向用例&#xff0c;在验证消息内容为空等情况时的消费正确性&#xff1b; 推送大批量MQ&#xff0c;通过Admin控制台查看MQ消费的情况&#xff0c;是否出现消费假死、…

etcd之etcd分布式锁及事务(四)

1、etcd分布式锁及事务 1.1 前言 分布式锁是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中&#xff0c;常常需要协调他们的动作。如 果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源&#xff0c;那么访问这些资源的时候&#xff0c;往往需要…

基于Ubuntu24.04,下载并编译Android12系统源码 (一)

1. 前言 1.1 编译源码可以干什么 定制Android系统将最新版本的Android系统刷入到自己的Android设备中将整个系统源码导入到Android Studio中&#xff08;可以不用编译源码来实现&#xff09;。 只要有对应的Android源码版本的android.iml和android.ipr文件&#xff0c;就可以…

移动开发(五):.NET MAUI中自定义主题设置

目录 一、.NET MAUI主题设置原理 二、.NET MAUI主题设置案例 2.1 创建主题文件 2.2 修改App.xaml 文件 2.3 设置默认主题的三种方式 2.4 通过按钮切换主题 三、.NET MAUI主题设置技巧 四、总结 今天给大家分享.NET MAUI应用中如何自定义主题&#xff0c;提升APP本身个性…