【华为OD题库-015】报文重排序-Java

题目

对报文进行重传和重排序是常用的可靠性机制,重传缓冲区内有一定数量的子报文,每个子报文在原始报文中的顺序已知,现在需要恢复出原始报文。
输入描述
输入第一行为N,表示子报文的个数,0<N <= 1000。
输入第二行为N个子报文,以空格分开,子报文格式为字符串报文内容+后缀顺序索引,字符串报文内容由(a-Z ,A-Z)组成。后缀为整形值,表示顺序。顺序值唯一 ,不重复。
输出描述:
输出恢复出的原始报文。按照每个子报文的顺序值的升席排序,顺序后缀需要从恢复出的报文中删除掉
用例1
输入:
rolling3 stone4 like1 a2
输出:
like a rolling stone
说明:
4个子报文的内容分别为roling,stone,like,a,顺序值分别为3, 4,1, 2,按照顺序值升序并删除掉顺序后缀得到恢复的原始报文:
like a rolling stone
用例2
输入:
Lgifts6 and7 Exchanging1 all2 precious5 things8 kinds3 of4
注:这里需要注意and7与Exchanging1有两个空格
输出:
Exchanging all kinds of precious gifts and things

思路

这道题本身不难。大概经过下面3步,即可得到答案。

  1. 将输入的字符串根据空格拆分为字符串数组
  2. 遍历数组,对于每一个字符串,找到其第一个数字的索引位置,根据该位置拆分为字符串和顺序值,存入map中(将顺序值作为key,字符串作为val存放)
  3. 再遍历hashmap,可以直接获得恢复出的原始报文(按照顺序值的从小到大顺序)
    问题的关键在于理解,当hashmap中的key为integer时,map自己就是按照从小到大的顺序排序的当然,这需要在一定约束条件下,下面详细分析。
    这需要从hashmap的存放逻辑说起。下图是hashmap的逻辑结构。
    在这里插入图片描述
    通过上图,可以看到hashmap是由数组、链表+红黑树构成。默认情况下,hashmap的初始容量为16,也就是数组个数为16个。
    当存放的元素个数大于16 * 0.75(负载因子)时,hashmap会触发扩容操作(原来的2倍,即16扩成32)。
    再来看hashmap存放键的逻辑(key类型为Integer),即put(key,val)到底怎么做的?
    通过源码很容易找到下述逻辑:
    public V put(K key, V value) {return putVal(hash(key), key, value, false, true);}
    static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}

hashmap是通过hash(key)计算存放位置的,而hash函数是返回的key的hashcode和其右移16位的的异或值。比如key值是16,那么其hashcode为16(Integer类型的hashcode返回其本身)。再通过异或计算得到的值还是为16.计算过程如下:
0000 0000 0001 0000 ^ //16的二进制表示
0000 0000 0000 0000 //右移16位,全为0。右移的原因是,可以让最后结果含有hashcode高16位的特征,使其在hashmap中存放得更均匀。
=0000 0000 0001 0000 //还是得到了16
上面通过hash函数(有人称扰动函数)获得了16,接下来看看怎么利用16计算其在hashmap的位置的(即存放hashmap数组的哪个索引?)
在这里插入图片描述
如上图所示,只关注圈出来的部分。计算位置i的方式为:i=(n - 1) & hash,其中n为当前hashmap的容量,hash为上一步hash(key)计算出来的值。所以当hash=16时,位置i=(16-1)&16=0。也就是在索引0处存放值。计算过程如下:
0000 1111 & //16-1=15的二进制表示
0001 0000 //16的二进制表示
=0000 0000 //结果为0,其实就是16%16的值。这也是为什么容量要设置为2的整数次幂的原因,因为对n等于2的整数次幂来说。x&(n-1)=x%n
结合上面的描述,我们用个具体实例来演示下hashmap的存放过程。
在这里插入图片描述

通过上面的过程,可以看到,在hashMapkey为Integer时,在一定条件下,可以直接按照key的从小到大的顺序输出。比如上面的步骤3,输出结果是0,2。步骤6输出结果是:0 2 3 4 5 6 7 8 9 10 11 16 17。但是步骤4输出的结果为:0 16 2。
现在需要考虑什么时候不能正确排序?显然,当hashmap不扩容时,输入的key又不小于当前容量时,会造成某个节点存放多个值,最后无法按照从小到大的顺序输出。
但是就我们这道题目来说,输入的数据范围只能是1~n这样连续的数字,n<=1000。不设置hashmap初始容量的情况下,hashmap的容量扩容过程应该为:16 32 64 128 256 1024。通过不断扩容最终不会存在某个节点有多个值的情况,所以可以按照key值从小到大的顺序输出。当然扩容不可避免的降低了效率。因为我们知道字符串的总量。我们可以在初始化hashmap时直接指定容量大小(不必我们自己计算为2的整数次幂,hashmap会自动完成这个操作)。
在这里插入图片描述

题解

package hwod;import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;public class MessageSort {static Map<Integer, String> map;public static void main(String[] args) {Scanner sc = new Scanner(System.in);int N = sc.nextInt();sc.nextLine();map = new HashMap<>(N);String[] inputs = sc.nextLine().split("\\s+");System.out.println(messageSort(inputs));}private static String messageSort(String[] inputs) {for (int i = 0; i < inputs.length; i++) {int idx = getFirstNum(inputs[i]);int num = Integer.parseInt(inputs[i].substring(idx));String val = inputs[i].substring(0, idx);map.put(num, val);}StringBuilder sb = new StringBuilder();//可以直接遍历map(key为Interger的hashmap在一定条件下可以按照key的从小到大排序)//也可以遍历1~N,直接取map.get(1)、map.get(2)……这样就不用利用上面分析的hashmap的特性了。for (Integer k : map.keySet()) {if (sb.length() != 0) {sb.append(" ");}sb.append(map.get(k));}return sb.toString();}private static int getFirstNum(String input) {char[] chars = input.toCharArray();for (int i = 0; i < chars.length; i++) {if (Character.isDigit(chars[i])) {return i;}}return -1;}
}

推荐

如果你对本系列的其他题目感兴趣,可以参考华为OD机试真题及题解(JAVA),查看当前专栏更新的所有题目。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/140622.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【FISCO BCOS】十九、区块链浏览器部署

目录 一、环境依赖 检查环境 1.检查java 二、拉取安装脚本 获取部署安装包 ​编辑 解压安装包 进入目录 三、修改配置 四、部署服务 五、状态检查 检查前后端进程 1.检查后端server进程 2.检查前端的nginx进程 检查进程端口 六、使用区块链浏览器 1.配置群组…

EDA实验-----3-8译码器设计(QuartusII)

目录 一. 实验目的 二. 实验仪器 三. 实验原理及内容 1.实验原理 2.实验内容 四&#xff0e;实验步骤 五. 实验报告 六. 注意事项 七. 实验过程 1.创建Verilog文件&#xff0c;写代码 ​编辑 2.波形仿真 3.连接电路图 4.烧录操作 一. 实验目的 学会Verilog HDL的…

【Java 进阶篇】Java与JQuery:探秘事件绑定、入口函数与样式控制

在现代的Web开发中&#xff0c;Java和JQuery是两个不可或缺的角色。Java为我们提供了强大的后端支持&#xff0c;而JQuery则是前端开发的得力助手。本篇博客将围绕Java和JQuery&#xff0c;深入探讨事件绑定、入口函数和样式控制&#xff0c;带你进入前端开发的奇妙世界。 Jav…

粉够荣获淘宝联盟区域理事会常务理事,携手共铸淘客新生态

淘宝联盟区域理事会于2021年成立&#xff0c;首届成立成都、广州、武汉&#xff0c;服务近2000个领军淘宝客企业&#xff0c;作为区域生态与官方交流重要枢纽&#xff0c;理事会举办近百场交流分享会&#xff0c;带动淘客跨域跨业态交流成长。 2023年9月7日第二届淘宝联盟理事…

【Maven教程】(十):使用 Hudson 进行持续集成—— 从Hudson的安装到任务创建 ~

Maven 使用 Hudson 进行持续集成 1️⃣ 持续集成的作用、过程和优势2️⃣ Hudson 简介与安装3️⃣ 准备 Subversion 仓库4️⃣ Hudson 的基本系统设置5️⃣ 创建 Hudson 任务5.1 Hudson 任务的基本配置5.2 Hudson 任务的源码仓库配置5.3 Hudson 任务的构建触发配置5.4 Hudson …

AI:86-基于深度学习的人体姿态估计与运动分析

🚀 本文选自专栏:人工智能领域200例教程专栏 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的代码,详细讲解供大家学习,希望可以帮到大家。欢迎订阅支持,正在不断更新中,…

Leetcode—2469.温度转换【简单】

2023每日刷题&#xff08;二十六&#xff09; Leetcode—2469.温度转换 实现代码 /*** Note: The returned array must be malloced, assume caller calls free().*/ double* convertTemperature(double celsius, int* returnSize) {double* ans (double *)malloc(sizeof(do…

Springboot+vue的高校办公室行政事务管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的高校办公室行政事务管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。…

某XX自考小程序的AES加密分析

前言 主要是报了自考在这个小程序上面做题&#xff0c;就研究了一下这个接口本文仅供学习交流使用&#xff0c;请勿随意传播。如有侵犯你的权益及时联系我删除。 一、抓包分析打开小程序&#xff0c;打开devtools 工具&#xff0c;这里就不啰嗦&#xff0c;直接上过程。 点击…

入选《人工智能领域内容榜》

2023-11-13 入选《人工智能领域内容榜》31 C# OpenCvSharp DNN HybridNets 同时处理车辆检测、可驾驶区域分割、车道线分割

maven 私有仓库配置

1.整体库信息 2.配置阿里云库 &#xff08;可以配置多个库&#xff0c;再引用代理库&#xff09; 3.建立自己的 发布&#xff0c;快照库 4.建立自由的公共库- 引用所有需要的库 5.maven setting 中配置 用户名密码 <server><id>mv-releases</id><usernam…

Java_常用API

API(全称Application Programming Interface:应用程序编程接口) String 常用方法 注意事项 每一次试图改变字符串对象都产生了新的字符串对象 ArrayList 常用方法 ATM系统 01系统架构搭建、欢迎页设计 02开户功能实现 03登录功能实现 04操作页展示、查询账户、退出账户 05存…

工作十年+的测试应该具备什么能力?

大概是2014年的时候&#xff0c;我开始接触面试工作&#xff0c;就是从应聘者转为面试官&#xff0c;记得印象深刻的是面试了一位做了8年的测试。对方气场很足&#xff0c;嗯&#xff0c;毕竟那时的我还只是一个3、4年经验的小测试&#xff0c;相反&#xff0c;印象深刻的并不是…

TikTok影响力经济:解锁社交媒体的商业机遇

社交媒体平台的崛起改变了我们与世界互动的方式&#xff0c;而TikTok作为其中的一员&#xff0c;已经成为全球范围内的现象。这个短视频应用不仅让用户在几秒钟内分享创意和娱乐&#xff0c;还为企业和创作者提供了巨大的商业机会。本文将深入探讨TikTok的影响力经济&#xff0…

【Go入门】struct类型

【Go入门】struct类型 struct Go语言中&#xff0c;也和C或者其他语言一样&#xff0c;我们可以声明新的类型&#xff0c;作为其它类型的属性或字段的容器。例如&#xff0c;我们可以创建一个自定义类型person代表一个人的实体。这个实体拥有属性&#xff1a;姓名和年龄。这样…

Ubuntu 20.04编译Chrome浏览器

本文记录chrome浏览器编译过程&#xff0c;帮助大家避坑qaq 官网文档&#xff1a;https://chromium.googlesource.com/chromium/src//main/docs/linux/build_instructions.md 一.系统要求 一台64位的英特尔机器&#xff0c;至少需要8GB的RAM。强烈推荐超过16GB。至少需要100…

基于Matlab+ AlexNet神经网络的动物识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于Matlab和AlexNet神经网络的动物识别系统可以用于自然图像识别等场景&#xff0c;以下是一个基本的介绍设计步骤…

项目笔记记录

一、node下载版本报错&#xff1a;npm install --legacy-peer-deps 二、Scheduled: 任务自动化调度 Scheduled 标记要调度的方法的注解&#xff0c;必须指定 cron&#xff0c;fixedDelay或fixedRate属性之一 fixedDelay&#xff1a;固定延迟 延迟执行任务&#xff0c;任务在…

论文笔记:Deep Trajectory Recovery with Fine-Grained Calibration using Kalman Filter

TKDE 2021 1 intro 1.1 背景 用户轨迹数据对于改进以用户为中心的应用程序很有用 POI推荐城市规划路线规划由于设备和环境的限制&#xff0c;许多轨迹以低采样率记录 采样的轨迹无法详细说明物体的实际路线增加了轨迹中两个连续采样点之间的不确定性——>开发有效的算法以…

高频SQL50题(基础班)-4

文章目录 主要内容一.SQL练习题1.1789-员工的直属部门代码如下&#xff08;示例&#xff09;: 2.610-判断三角形代码如下&#xff08;示例&#xff09;: 3.180-连续出现的数字代码如下&#xff08;示例&#xff09;: 4.1164-指定日期的产品价格代码如下&#xff08;示例&#x…