牛客网-华为机考-HJ30 字符串合并处里--详细解题思路,并有详细解题代码和注解

2023-11-15

注意:代码和解题思路在后面

HJ30 字符串合并处理

描述 按照指定规则对输入的字符串进行处理。

详细描述:

第一步:将输入的两个字符串str1和str2进行前后合并。如给定字符串 “dec” 和字符串 “fab” , 合并后生成的字符串为 “decfab”

第二步:对合并后的字符串进行排序,要求为:下标为奇数的字符和下标为偶数的字符分别从小到大排序。这里的下标的意思是字符在字符串中的位置。注意排序后在新串中仍需要保持原来的奇偶性。例如刚刚得到的字符串“decfab”,分别对下标为偶数的字符’d’、‘c’、‘a’和下标为奇数的字符’e’、‘f’、'b’进行排序(生成 ‘a’、‘c’、‘d’ 和 ‘b’ 、‘e’ 、‘f’),再依次分别放回原串中的偶数位和奇数位,新字符串变为“abcedf”

第三步:对排序后的字符串中的’0’‘9’、‘A’‘F’和’a’~'f’字符,需要进行转换操作。

转换规则如下:

对以上需要进行转换的字符所代表的十六进制用二进制表示并倒序,然后再转换成对应的十六进制大写字符(注:字符 a~f 的十六进制对应十进制的10~15,大写同理)。

如字符 ‘4’,其二进制为 0100 ,则翻转后为 0010 ,也就是 2 。转换后的字符为 ‘2’。

如字符 ‘7’,其二进制为 0111 ,则翻转后为 1110 ,对应的十进制是14,转换为十六进制的大写字母为 ‘E’。

如字符 ‘C’,代表的十进制是 12 ,其二进制为 1100 ,则翻转后为 0011,也就是3。转换后的字符是 ‘3’。

根据这个转换规则,由第二步生成的字符串 “abcedf” 转换后会生成字符串 “5D37BF”。

数据范围:输入的字符串长度满足 1≤n≤100

输入描述:

样例输入两个字符串,用空格隔开。

输出描述:

输出转化后的结果。

示例1

输入:

dec fab

输出:

5D37BF

示例2

输入:

ab CD

输出:

3B5D

说明:

合并后为abCD,按奇数位和偶数位排序后是CDab(请注意要按ascii码进行排序,所以C在a前面,D在b前面),转换后为3B5D

示例3

输入:

123 15

输出:

88C4A

参考思路和代码及详细注释

参考思路;

1、先合并字符串
2、将合并后的字符串进行排序并转换成字符数组
3、按照规则计算得到最终结果:
	规则1:如果字符是字母,则先将字母转换成十进制,再将十进制转换成二进制,再将二进制翻转,再将翻转后的二进制张成十进制,如果转换成十进制后的
        数据在[10,15]区间,则将其转换成对应16进制大小字母并写入结果字符串中,如果转换好后的十进制在其他区间,则直接写入结果字符串中。
    规则2:如果字符是数字,则先将数字转换成二进制,再降二进制翻转,再将翻转后的二进制转换成十进制,如果转换成十进制后的数据在 
        [10,15]区间,则将其转换成对应16进制大小字母并写入结果字符串中,如果转换好后的十进制在其他区间,则直接写入结果字符串中。
    规则3:这是个坑,一定要注意。如果不在[a,f]或者[A,F]区间的则直接写入结果字符串中。我在写的时候没有注意这个,所以提交结果测试         半天,结果集不对
        测试数据:Eqr v9oEb12U2ur4xu7rd931G1f50qDo
        没有加规则3时答案:8084842CAE9B97D7BF
        加了规则3后答案:8084842CAE9B9G7D7BUFooqqrrrvuxu

参考代码和详细注释:

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;

/**
 * @Author lqs
 * @Date 2022年05月19日 10:12:04
 * @Version 1.0.0
 * @ClassName ms
 * @Describe
 */
public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String[] split = input.nextLine().split(" ");
        //合并字符串
        String mergeStr = mergeString(split);
        //测试用
//        System.out.println(mergeStr);
        //排序字符串
        char[] parityIndexSort = parityIndexSort(mergeStr);
        //测试用
//        for (char c : parityIndexSort) {
//            System.out.print(c + " ");
//        }
        //按照规则转换字符串,并输出转换后的结果
        System.out.println(ruleConversion(parityIndexSort));

    }

    /**
     * 将多个字符串按照顺序合并为一个字符串
     *
     * @param strArray 传入需要合并的字符串数组
     * @return 返回按照顺序合并好后的数组
     */
    private static String mergeString(String[] strArray) {
        StringBuilder mergeStr = new StringBuilder();
        for (String s : strArray) {
            mergeStr.append(s);
        }
        return mergeStr.toString();
    }

    /**
     * 对需要排序的字符串,按照奇数和偶数下标对应的值进行排序,并返回按照奇数和偶数下标排序好后的字符数组
     *
     * @param sortStr 需要按照奇数和偶数下标对应值进行排序的字符串
     * @return 返回排序好后的字符串
     */
    private static char[] parityIndexSort(String sortStr) {
        char[] sortArray = sortStr.toCharArray();
        ArrayList<Character> oddNumber = new ArrayList<>();//奇数下标值数组
        ArrayList<Character> even = new ArrayList<>();//偶数下标值数组
        //先按照奇、偶进行分组排序
        oddNumber.add(sortArray[1]);
        even.add(sortArray[0]);
        for (int i = 2; i < sortArray.length; i++) {
            if (i % 2 == 0) {
                even.add(sortArray[i]);
            } else {
                oddNumber.add(sortArray[i]);
            }
        }

        //对奇数下标对应值进行排序
        oddNumber.sort(new Comparator<Character>() {
            @Override
            public int compare(Character o1, Character o2) {
                return o1 - o2;
            }
        });

        //对偶数下标对应值进行排序
        even.sort(new Comparator<Character>() {
            @Override
            public int compare(Character o1, Character o2) {
                return o1 - o2;
            }
        });

        //将排序好的奇数和偶数下标索引对应的值按奇数和偶数下标对应对应的值合并到一起
        sortArray[0] = even.get(0);
        sortArray[1] = oddNumber.get(0);
        int i = 1;
        int j = 1;
        for (int k = 2; k < sortArray.length; k++) {
            if (k % 2 == 0) {
                sortArray[k] = even.get(i++);
            } else {
                sortArray[k] = oddNumber.get(j++);
            }
        }

        return sortArray;

    }

    /**
     * 将字符数组按照规则进行转换
     * 规则1:如果字符是字母,则先将字母转换成十进制,再将十进制转换成二进制,再将二进制翻转,再将翻转后的二进制张成十进制,如果转换成十进制后的
     * 数据在[10,15]区间,则将其转换成对应16进制大小字母并写入结果字符串中,如果转换好后的十进制在其他区间,则直接写入结果字符串中。
     * 规则2:如果字符是数字,则先将数字转换成二进制,再降二进制翻转,再将翻转后的二进制转换成十进制,如果转换成十进制后的数据在[10,15]区间,则
     * 将其转换成对应16进制大小字母并写入结果字符串中,如果转换好后的十进制在其他区间,则直接写入结果字符串中。
     * 规则3:这是个坑,一定要注意。如果不在[a,f]或者[A,F]区间的则直接写入结果字符串中。我在写的时候没有注意这个,所以提交结果测试半天,结果集不对
     * 测试数据:Eqr v9oEb12U2ur4xu7rd931G1f50qDo
     * 没有加规则3时答案:8084842CAE9B97D7BF
     * 加了规则3后答案:8084842CAE9B9G7D7BUFooqqrrrvuxu
     *
     * @param sortCharArray 需要按规则转换的字符数组
     * @return 返回按规则转换好后的数组
     */
    private static String ruleConversion(char[] sortCharArray) {
        StringBuilder ruledConversionStr = new StringBuilder();
        for (char c : sortCharArray) {
            if (Character.isLetter(c)) {//处理a~f或者A~F
                char toUpperCase = Character.toUpperCase(c);
                if (toUpperCase >= 'A' && toUpperCase <= 'F') {
                    //将对应的字母转换为十进制
                    int letterToDecimal = getLetterToDecimal(toUpperCase);
                    //将转换好后的十进制转换成二进制翻转后再转换成十进制
                    int flipBinaryToDecimal = getDecimalToBinaryAndFlipBinaryToDecimal(letterToDecimal);
                    //如果转换后的十进制是大于等于10,小于等于15,则转换成16进制对应的字母
                    if (flipBinaryToDecimal >= 10 && flipBinaryToDecimal <= 15) {
                        //将数字转换成对应16进制的大写字母,并写入结果字符串中
                        ruledConversionStr.append(getDecimalToLetter(flipBinaryToDecimal));
                    } else {//小于10大于等于0的十进制数直接写入结果字符串中
                        ruledConversionStr.append(flipBinaryToDecimal);
                    }
                } else {//注意!注意!注意!如果不在[a,f]或者[A,F]区间的则直接写入结果字符串中
                    ruledConversionStr.append(c);
                }
            } else {//对0~9进行处理
                //将数字转化为二进制,再对二进制进行翻转,在把翻转后的二进制转换成十进制
                int decimalToBinaryAndFlipBinaryToDecimal = getDecimalToBinaryAndFlipBinaryToDecimal(Integer.parseInt(String.valueOf(c)));
                if (decimalToBinaryAndFlipBinaryToDecimal >= 10 && decimalToBinaryAndFlipBinaryToDecimal <= 15) {
                    ruledConversionStr.append(getDecimalToLetter(decimalToBinaryAndFlipBinaryToDecimal));
                } else {
                    ruledConversionStr.append(decimalToBinaryAndFlipBinaryToDecimal);
                }
            }
        }

        return ruledConversionStr.toString();
    }

    /**
     * 将字母转换成对应的十进制
     *
     * @param c 需要转换的为十进制的字母
     * @return 返回字母转换好后的十进制
     */
    private static int getLetterToDecimal(char c) {
        ;
        switch (c) {
            case 'A':
                return 10;
            case 'B':
                return 11;
            case 'C':
                return 12;
            case 'D':
                return 13;
            case 'E':
                return 14;
            case 'F':
                return 15;
        }
        return 0;
    }

    /**
     * 将十进制的数组转换成二进制后,再对二进制翻转,再将翻转后的二进制转换成十进制
     *
     * @param number 传入需要转换的十进制
     * @return 返回转换好后的十进制数字
     */
    private static int getDecimalToBinaryAndFlipBinaryToDecimal(int number) {
        ArrayList<Integer> flipBinary = new ArrayList<>();
        int tmp = number;
        for (int i = 1; i <= tmp; i++) {
            if (number % 2 == 0) {
                flipBinary.add(0);
                number /= 2;
            } else {
                flipBinary.add(1);
                number /= 2;
            }
            if (number == 1) {
                flipBinary.add(1);
                break;
            }
        }
        //如果计算出来的二进制没有四位,则在其后面补0
        while (flipBinary.size() < 4) {//while循环是先做后判断
            flipBinary.add(0);
        }

        return getBinaryToDecimal(flipBinary);
    }

    /**
     * 将二进制转换成十进制
     *
     * @param binary 需要转换的二进制列表
     * @return 返回转换好后的十进制数
     */
    private static int getBinaryToDecimal(ArrayList<Integer> binary) {
        int n = binary.size();
        int decimalNumber = 0;
        for (int i = 0; i < n; i++) {
            decimalNumber += Math.pow(2, n - i - 1) * binary.get(i);//pow:求2的n-i-1次方的值,100,1*pow(2,3-0-1)+1*pow(2,3-1-1)+1*pow(2,3-2-1)
        }

        return decimalNumber;
    }

    /**
     * 将数字转换成对应的16进制的大写字母
     *
     * @param number 需要转换的数字
     * @return 返回转换好后的字母
     */
    private static char getDecimalToLetter(int number) {
        switch (number) {
            case 10:
                return 'A';
            case 11:
                return 'B';
            case 12:
                return 'C';
            case 13:
                return 'D';
            case 14:
                return 'E';
            case 15:
                return 'F';
        }
        return 'X';
    }

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

牛客网-华为机考-HJ30 字符串合并处里--详细解题思路,并有详细解题代码和注解 的相关文章

随机推荐

  • iOS巅峰之点击UIAlertView的灰色部分也能dismiss消失

    UIAlertView alert UITapGestureRecognizer recognizerTap void viewDidLoad super viewDidLoad Do any additional setup after
  • This action could not be completed. Try again.

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 遇到this action could not be completed try again 22421 淡定 解决方法 确保网页上iTunes Connect已经remo
  • 快手投放广告,快手广告优势有哪些呢?

    快手在短视频领域已积累大量忠实用户 形成为独特的社区文化和 老铁经济 虽然商业化进程谨慎而缓慢 但从长远来看 兼顾用户体验的商业需求也许有利于平台商业化的持续发展 对于创作者来说 在入驻一个新平台之前 需要对平台的整体调性全面了解 快手是更
  • 软件工程第一节课 课程引言

    课程引言 一 需要网站系统开发需要掌握的技术 网站的开发技术有很多 主要包括CGI ASP PHP JSP ASP NET等 每一种技术都有其自身的特点与局限性 具体的网站开发技术要根据网站的功能需求 面对的受众 访问量 开发者熟悉的技术等
  • 开源协议说明LGPL

    文章目录 闭源程序 LGPL 闭源程序 不以某种形式开放源代码 也就是说 用户 包括其他开发者 不能获取其源代码的程序 LGPL LGPL协议是一个商业友好的协议 这里的含义是 你可以用 LGPL协议开发商业程序 当然也可以是非商业的闭源程
  • Android最常用八种加密算法

    原文链接 http blog csdn net smartbetter http blog csdn net u013718120 article details 56486408 项目地址 https github com Yalanti
  • 大一python字典作业

    1 字典操作综合练习一 定义一个字典 goods Apple 4999 华为 3600 Vivo 2999 OPPO 3200 三星 4300 向字典新增一个 小米 手机 价格为2800 将字典中 华为 品牌手机价格修改为3999 输入任一
  • Linux网络设备的系统调用

    转自 http www tuicool com articles QJfmUr 在用户层上的程序 建立本地socket后 使用ioctl读取phy芯片的寄存器 ioctl sockfd SIOCGMIIREG ifr 下面是linux的网络
  • html 快捷输入代码

    快捷输入代码 输入 html 5 回车 输入 div 数量 如 d
  • sklearn学习——特征处理

    sklearn学习 特征处理 特征提取 feature extraction 从文字 图像 声音等其他非结构化数据中提取新信息作为特征 比如说 从淘宝宝贝的名称中提取出产品类别 产品颜色 是否是网红产品等等 特征创造 feature cre
  • 使用Java8新特性对List对象进行遍历、过滤、排序等处理

    使用java8 新特性stream流对List对象进行遍历 过滤 查询 去重 排序 分组 新建一个名为Student的类 包含以下属性 public class Student private String name private int
  • elk笔记16--aggs-Metrics Aggregations

    elk笔记16 aggs Metrics Aggregations 1 Metrics Aggregations 简介 2 Metrics Aggregations 分类 2 1 Avg Aggregation 2 2 Weighted A
  • python: 理解__str__

    以下是我的理解 如果有错我的地方 请务必告诉我 不胜感激 在python语言里 str 一般是格式是这样的 class A def str self return this is in str 事实上 str 是被print函数调用的 一般
  • matplotlib绘制出光滑曲线

    用matplotlib库绘制光滑的曲线图 注意点 坐标要是用range 表示的话用这个方法拟合平滑曲线会报错 查了别人说的把range 转化成list range 感觉并没有用 所以还是用了穷举法表示的x坐标 import numpy as
  • MOM和MES区别

    对于工业软件 中国的制造业企业并不模式 尤其是在生产排产过程中 MES 制造执行系统 的应用早已普及 不过 SiemensPLM Software DER业务中国区总经理戚锋近日在接受记者采访时表示 MES已经无法跟上时代潮流 MES 的升
  • 机器学习(周志华) 习题 参考答案 第十六章

    周志华老师的 机器学习 的第16章的习题答案较少 网上的参考答案链接分别为答案一和答案二 以下是个人对这章的习题的理解 如有问题 欢迎指正 16 1比较UCB方法与 贪心法和Softmax方法的异同 1 UCB选则值最大的摇臂 是100 选
  • python 词频统计

    python 词频统计 描述 谁动了我的奶酪 是美国作家斯宾塞 约翰逊创作的一个寓言故事 该书首次出版于1998年 书中主要讲述4个 人物 两只小老鼠 嗅嗅 Sniff 匆匆 Scurry 和两个小矮人 哼哼 Hem 唧唧 Haw 找寻奶酪
  • Use gitk to understand git

    https lostechies com joshuaflanagan 2010 09 03 use gitk to understand git
  • 红帽认证-RHCSA

    目录 RHCSA认证考的是 Server A 题目 一 按要求配置网络 二 配置系统使用默认存储库 三 调试SELinux 四 创建用户账户 五 配置cron 作业 六 创建协作目录 七 配置NTP 八 配置 autofs 九 配置 var
  • 牛客网-华为机考-HJ30 字符串合并处里--详细解题思路,并有详细解题代码和注解

    注意 代码和解题思路在后面 HJ30 字符串合并处理 描述 按照指定规则对输入的字符串进行处理 详细描述 第一步 将输入的两个字符串str1和str2进行前后合并 如给定字符串 dec 和字符串 fab 合并后生成的字符串为 decfab