【华为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 2048(容量为1024时,如果元素量超过了1024*0.75=768,还会触发一次扩容)。通过不断扩容最终不会存在某个节点有多个值的情况,所以可以按照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.rhkb.cn/news/194396.html

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

相关文章

Unity 2021 LTS / Unity 2022 LTS New Shader Graph Node 参考样本

Shader Graph团队很高兴地宣布发布新的节点参考样本&#xff0c;现在可用于2021 LTS, 2022 LTS和未来的版本。 节点参考样本是超过140个Shader图形资源的集合。您可以将这些图用作参考&#xff0c;以了解每个节点的作用及其工作原理&#xff0c;而不是在项目中使用这些图。每个…

【软件安装】Centos系统中安装docker容器(华为云HECS云耀服务器)

这篇文章&#xff0c;主要介绍Centos系统中安装docker容器&#xff08;华为云HECS云耀服务器&#xff09;。 目录 一、安装docker 1.1、卸载旧版本docker 1.2、更新repo镜像 1.3、安装依赖包 1.4、添加docker-ce镜像 1.5、安装docker-ce 1.6、查看docker安装版本 1.7、…

Opengauss到Oracle增量同步, 使用debezium

一、概述 PG到Oracle的同步方案使用debezium kafka kafka-connect-jdbc。debezium是一款开源的变更捕获软件&#xff0c;它以kafka的connector形式运行&#xff0c;可以捕获PostgreSQL、MySQL、Oracle中的变更数据&#xff0c;保存到kafka。kafka-connect-jdbc是confluent公…

[Linux] ssh远程访问及控制

一、ssh介绍 1.1 SSH简介 SSH&#xff08;Secure Shell&#xff09;是一种安全通道协议&#xff0c;主要用于实现远程登录、远程复制等功能的字符接口。SSH 协议包括用户在登录时输入的用户密码、双方之间的通信。 加密数据传输&#xff0c;SSH 是一种建立在应用层和传输层上…

Please No More Sigma(构造矩阵)

Please No More Sigma 给f(n)定义如下&#xff1a; f(n)1 n1,2; f(n)f(n-1)f(n-2) n>2; 给定n&#xff0c;求下式模1e97后的值 Input 第一行一个数字T&#xff0c;表示样例数 以下有T行&#xff0c;每行一个数&#xff0c;表示n。 保证T<100&#xff0c;n<100000…

【Proteus仿真】【Arduino单片机】DHT11温湿度

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用PCF8574、LCD1602液晶、DHT11温湿度传感器等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示传感器采集温度和湿度。 二、软件设…

SQL存储过程和函数

SQL存储过程和函数 变量系统变量用户定义变量局部变量 存储过程存储函数 变量 在MySQL中变量分为三种类型: 系统变量、用户定义变量、局部变量。 系统变量 系统变量 是MySQL服务器提供&#xff0c;不是用户定义的&#xff0c;属于服务器层面。分为全局变量&#xff08;GLOBA…

全栈工程师必须要掌握的前端Html技能

作为一名全栈工程师&#xff0c;在日常的工作中&#xff0c;可能更侧重于后端开发&#xff0c;如&#xff1a;C#&#xff0c;Java&#xff0c;SQL &#xff0c;Python等&#xff0c;对前端的知识则不太精通。在一些比较完善的公司或者项目中&#xff0c;一般会搭配前端工程师&a…

Mistral 7B 比Llama 2更好的开源大模型 (二)

Mistral 7B 论文学习 Mistral 7B 论文链接 https://arxiv.org/abs/2310.06825 代码: https://github.com/mistralai/mistral-src 网站: https://mistral.ai/news/announcing-mistral-7b/ 论文摘要 Mistral 7B是一个70亿参数的语言模型,旨在获得卓越的性能和效率。Mistral 7…

C# 使用Microsoft.Office.Interop.Excel库操作Excel

1.在NuGet管理包中搜索&#xff1a;Microsoft.Office.Interop.Excel&#xff0c;如下图红色标记处所示&#xff0c;进行安装 2. 安装完成后&#xff0c;在程序中引入命名空间如下所示&#xff1a; using Microsoft.Office.Interop.Excel; //第一步 添加excel第三方库 usi…

算法笔记-贪心1

算法笔记-贪心 什么是贪心算法分配饼干例题理解二分割字符串最优装箱整数配对最大组合整数分配区间问题买股票的最佳时机区间选点 问题什么是贪心算法 分配饼干例题 //贪心算法 //保证局部最优,从而使最后得到的结果是全局最优的 #include<iostream> #include<a…

VIVADO+FPGA调试记录

vivadoFPGA调试记录 vitis编译vivado导出的硬件平台&#xff0c;提示xxxx.h file cant findVITIS内定义的头文件找不到 vitis编译vivado导出的硬件平台&#xff0c;提示’xxxx.h file cant find’ 此硬件平台中&#xff0c;包含有AXI接口类型的ip。在vitis编译硬件平台时&…

【漏洞复现】maccms苹果cms 命令执行漏洞

漏洞描述 感谢提供更多信息。“苹果CMS” 似乎是指 “Maccms”&#xff0c;这是一款开源的内容管理系统&#xff0c;主要用于搭建视频网站。Maccms 提供了一套完整的解决方案&#xff0c;包括用户管理、视频上传、分类管理、数据统计等功能&#xff0c;使用户能够方便地创建和…

如何构建风险矩阵?3大注意事项

风险矩阵法&#xff08;RMA&#xff09;是确定威胁优先级别的最有效工具之一&#xff0c;可以帮助项目团队识别和评估项目中的风险&#xff0c;帮助项目团队对风险进行排序&#xff0c;清晰地展示风险的可能性和严重性&#xff0c;为项目团队制定风险管理策略提供依据。 如果没…

【ArcGIS处理】行政区划与流域区划间转化

【ArcGIS处理】行政区划与流域区划间转化 引言数据准备1、行政区划数据2、流域区划数据 ArcGIS详细处理步骤Step1&#xff1a;统计行政区划下子流域面积1、创建批量处理模型2、添加批量裁剪处理3、添加计算面积 Step2&#xff1a;根据子流域面积占比均化得到各行政区固定值 参考…

hadoop 大数据环境配置 配置jdk, hadoop环境变量 配置centos环境变量 hadoop(五)

1. 遗漏一步配置系统环境变量&#xff0c;下面是步骤&#xff0c;别忘输入更新系统环境命令 2. 将下载好得压缩包上传至服务器&#xff1a; /opt/module 解压缩文件存放地址 /opt/software 压缩包地址 3. 配置环境变量&#xff1a; 在/etc/profile.d 文件夹下创建shell文件 …

Linux Traefik工具Dashboard结合内网穿透实现远程访问

文章目录 前言1. Docker 部署 Trfɪk2. 本地访问traefik测试3. Linux 安装cpolar4. 配置Traefik公网访问地址5. 公网远程访问Traefik6. 固定Traefik公网地址 前言 Trfɪk 是一个云原生的新型的 HTTP 反向代理、负载均衡软件&#xff0c;能轻易的部署微服务。它支持多种后端 (D…

2023亚太杯数学建模思路 - 复盘:人力资源安排的最优化模型

文章目录 0 赛题思路1 描述2 问题概括3 建模过程3.1 边界说明3.2 符号约定3.3 分析3.4 模型建立3.5 模型求解 4 模型评价与推广5 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 描述 …

网络和Linux网络_2(套接字编程)socket+UDP网络通信代码

目录 1. 预备知识 1.1 源IP地址和目的IP地址 1.2 端口号port和套接字socket 1.3 网络通信的本质 1.4 TCP和UDP协议 1.5 网络字节序 2. socket套接字 2.1 socket创建套接字 2.2 bind绑定 2.3 sockaddr结构体 3. UDP网络编程 3.1 server的初始化服务器 3.2 server的…

如何解决3d max渲染效果图全白这类异常问题?

通过3d max渲染效果图时&#xff0c;经常会出现3Dmax渲染效果图全黑或是3Dmax渲染效果图全白这类异常问题。可能遇到这类问题较多的都是新手朋友。不知如何解决。 3dmax渲染出现异常的问题&#xff0c;该如何高效解决呢&#xff1f;今天小编这里整理几项知识点&#xff0c;大家…