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

news2024/9/20 7:49:10

题目

对报文进行重传和重排序是常用的可靠性机制,重传缓冲区内有一定数量的子报文,每个子报文在原始报文中的顺序已知,现在需要恢复出原始报文。
输入描述
输入第一行为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.coloradmin.cn/o/1203080.html

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

相关文章

深入理解Kafka3.6.0的核心概念,搭建与使用

Kafka是最初由Linkedin公司开发&#xff0c;是一个分布式、支持分区的&#xff08;partition&#xff09;、多副本的&#xff08;replica&#xff09;&#xff0c;基于zookeeper协调的分布式消息系统&#xff0c;它的最大的特性就是可以实时的处理大量数据以满足各种需求场景&a…

卫星位置解算

武大GPS原理及应用 1.导航电文

探秘 Vue 数据绑定:为何 data 必须是函数而非对象?

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、实…

削峰填谷:居民小区电动汽车有序充电策略研究

摘 要&#xff1a;针对电动汽车在居民小区无序充电对电网系统产生严重隐患及充电间时过长问题&#xff0c;提出一种采用延迟充电的电动汽车有序充电控制策略&#xff0c;并在分析国内外电动汽车有序充电的研究现状后&#xff0c;设计了居民小区电动汽车有序充电策略的总体框架。…

双十一大促已过,虾皮、Lazada年底如何通过测评补单打造搜索排名

双十一大促已过&#xff0c;有人欢喜有人忧&#xff0c;不管怎么样&#xff0c;年底的这波旺季还是要好好把握的。 如何提升虾皮搜索排名 1、标题关键词匹配度 Shopee、Lazada的排名规则主要是根据用户搜索时输入的关键字和卖家的商品标题、描述等是否相匹配来进行排名&…

独立站商品信息是怎么获取的呢

独立站商品信息的获取主要通过以下几种方式&#xff1a; 人工收集&#xff1a;卖家可以通过在各个电商平台、网站等渠道进行手动搜索和收集商品信息&#xff0c;包括商品名称、价格、描述、图片等&#xff0c;然后将其导入到自己的独立站中。使用采集工具&#xff1a;目前市面…

解决 Django 开发中的环境配置问题:Windows 系统下的实战指南20231113

简介&#xff1a; 在本文中&#xff0c;我想分享一下我最近在 Windows 环境下进行 Django 开发时遇到的一系列环境配置问题&#xff0c;以及我是如何一步步解决这些问题的。我的目标是为那些可能遇到类似困难的 Django 开发者提供一些指导和帮助。 问题描述&#xff1a; 最近…

Vite - 配置 - 环境变量的配置详解

什么是环境变量 会根据当前的代码环境 产生值的变换的变量 就叫做 环境变量。简单来说&#xff0c;一个名为 APP_NAME 的变量&#xff0c; 在开发环境下&#xff0c;我们希望它的值是 ”测试的名称“&#xff1b; 在正式环境下&#xff0c;我们希望它的值是 ”正式的名称“。这…

【LeetCode】每日一题 2023_11_13 区域和检索 - 数组可修改(树状数组/线段树)

文章目录 刷题前唠嗑题目&#xff1a;区域和检索 - 数组可修改题目描述代码与解题思路偷看大佬题解 结语 刷题前唠嗑 LeetCode? 启动&#xff01;&#xff01;&#xff01; 今天是中等题&#xff0c;貌似挺简单的&#xff0c;先试试水 题目&#xff1a;区域和检索 - 数组可修…

2012年7月2日 Go生态洞察:Google I/O 2012的Go视频精选

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

vue3配置环境变量,小白简单易学

环境变量的意义就是防止我们更新打包的时候写错变量&#xff0c;合并代码这些一系列问题 首先看看效果 左边是本地测试环境&#xff0c;右边是打包后的生产环境&#xff0c;写这个环境变量的好处就是&#xff0c;你在本地开发的时候变量随便改&#xff0c;不会影响生产环境&am…

“大学生”返乡投身乡村建设,直播电商成为返乡创业新潮流!

数字乡村建设是新时代乡村振兴的必经之路&#xff0c;它是伴随网络化、信息化和数字化在农业农村经济社会发展中的应用&#xff0c;以及农民现代信息技能的提高而内生的农业农村现代化发展和转型进程&#xff0c;既是乡村振兴的战略方向&#xff0c;也是建设数字中国的重要内容…

基于DBO算法的WSN节点覆盖优化

先做一个声明&#xff1a;文章是由我的个人公众号中的推送直接复制粘贴而来&#xff0c;因此对智能优化算法感兴趣的朋友&#xff0c;可关注我的个人公众号&#xff1a;启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法&#xff0c;经典的&#xff0c;或者是近几年…

C++编程爬虫代码全过程分享

以下是使用C编写一个爬虫程序的基本步骤和代码示例&#xff1a; 1、首先&#xff0c;我们需要包含必要的库文件。在这个例子中&#xff0c;我们将使用<iostream>、<string>和<curlpp/cURLpp.hpp>库。 #include <iostream> #include <string> #i…

shell 语法介绍

大家好&#xff0c;我是蓝胖子&#xff0c;在日常开发中或多或少都会接触到shell脚本&#xff0c;可以说会shell脚本是一位后端开发的基本功&#xff0c;今天我将会花上一篇文章总结下常见的shell的语法&#xff0c;学完本篇&#xff0c;相信简单的shell脚本就能够看懂了&#…

世微 降压恒流 12V 5A 一切一双灯 LED汽车大灯驱动方案 AP5191

AP5191是一款PWM工作模式,高效率、外围简 单、内置功率MOS管&#xff0c;适用于4.5-150V输入的高 精度降压LED恒流驱动芯片。输出功率150W&#xff0c; 电流6A。 AP5191可实现线性调光和PWM调光&#xff0c;线性调 光脚有效电压范围0.55-2.6V. AP5191 工作频率可以通过RT 外部…

想要检测TikTok网络是否安全?这五个网站请收好

Tiktok目前在海外大火&#xff0c;越来越多的人想要进入TikTok的海外市场并捞一桶金。然而&#xff0c;成功并非易事。想要在TikTok中立足&#xff0c;我们必须保证我们的设备、网络环境和网络节点完全符合官方的要求&#xff0c;并且没有任何异常或风险。那么我们该如何设置、…

MAC地址注册的原理和应用

MAC地址注册是指在网络设备中&#xff0c;将设备的物理地址&#xff08;即MAC地址&#xff09;与设备的IP地址进行关联和注册的过程。MAC地址是以太网卡硬件上的独特标识符&#xff0c;用于在局域网中标识网络设备。 MAC地址注册在网络管理中起到重要作用&#xff0c;它可以帮助…

Python 框架学习 Django篇 (十) Redis 缓存

开发服务器系统的时候&#xff0c;程序的性能是至关重要的。经过我们前面框架的学习&#xff0c;得知一个请求的处理基本分为接受http请求、数据库处理、返回json数据&#xff0c;而这3个部分中就属链接数据库请求的响应速度最慢&#xff0c;因为数据库操作涉及到数据库服务处理…

2011年12月21日 Go生态洞察:了解Go社区

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…