华为OD机试真题 Java 实现【字符串摘要】【2023 B卷 100分】,附详细解题思路-LMLPHP

专栏导读

本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷)》

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

华为OD机试真题 Java 实现【字符串摘要】【2023 B卷 100分】,附详细解题思路-LMLPHP

一、题目描述

给定一个字符串的摘要算法,请输出给定字符串的摘要值:

  1. 去除字符串中非字母的符号;
  2. 如果出现连续字符(不区分大小写),则输出该字符(小写)+连续出现的次数;
  3. 如果时非连续的字符(不区分大小写),则输出该字符(小写)+该字母之后字符串中出现该字符的次数;
  4. 对按照以上方式表示后的字符串进行排序,字母和紧随的数字作为一组进行排序,数字大的在前,数字相同时,按字母进行排序,字母小的在前;

二、输入描述

一行字符串。

三、输出描述

摘要字符串。

四、解题思路

1、核心思路:

  1. 如果当前字母和上一个字母相同,该字母连续次数记为+1;
  2. 如果当前字母和上一个字母不同;
    • 如果当前字符的连续次数大于1,表示是连续字符,输出即可;
    • 如果只有1个,则要获取后面字符串中该字符的个数;
  3. 字母和紧随的数字作为一组进行排序,数字大的在前,数字相同时,按字母进行排序,字母小的在前;

2、具体思路如下:

  1. 输入一行字符串,不区分大小写;
  2. 定义一个数组chCountArr,记录字母出现的次数;
  3. 定义一个字符串,存储字符串中的字母;
  4. 定义一个集合,记录统计连续字符和非连续字符的字符和个数;
  5. 遍历输入的字符串;
  6. 如果当前字母和上一个字母相同,该字母连续次数记为+1;
  7. 如果当前字母和上一个字母不同;
    • 如果当前字符的连续次数大于1,表示是连续字符,输出即可;
    • 如果只有1个,则要获取后面字符串中该字符的个数;
    • 更新current连续次数为1;
  8. 字母和紧随的数字作为一组进行排序,数字大的在前,数字相同时,按字母进行排序,字母小的在前;
  9. 输出摘要字符串;

五、Java算法源码

package com.guor.od;

import java.util.Scanner;
import java.util.*;

public class OdTest03 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 不区分大小写
        String line = sc.nextLine().toLowerCase();

        // 字母出现的次数
        int[] chCountArr = new int[128];

        // 字符串中的字母
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < line.length(); i++) {
            char c = line.charAt(i);
            if (c >= 'a' && c <= 'z') {
                chCountArr[c]++;
                builder.append(c);
            }
        }

        line = builder.toString();

        // 统计连续字符和非连续字符的字符和个数
        List<MyCharBean> charList = new ArrayList<MyCharBean>();

        // 该字母连续次数记为1
        int continuousCount = 1;

        // 遍历输入的字符串
        for (int i = 0; i < line.length(); i++) {
            // 当前字母
            char current = line.charAt(i);
            // 下一个字符
            char next = ' ';
            // 如果不是最后一个字符
            if (i + 1 != line.length()) {
                next = line.charAt(i + 1);
            }

            // 后面字符串中该字母的连续个数
            chCountArr[current]--;

            // 如果当前字母和上一个字母相同,该字母连续次数记为+1
            if (current == next) {
                continuousCount++;
                // 如果当前字母和上一个字母不同
            } else {
                // 如果当前字符的连续次数大于1,表示是连续字符,输出即可
                // 如果只有1个,则要获取后面字符串中该字符的个数
                int num = continuousCount > 1 ? continuousCount : chCountArr[current];
                charList.add(new MyCharBean(current, num));
                // 更新current连续次数为1
                continuousCount = 1;
            }
        }

        // 字母和紧随的数字作为一组进行排序,数字大的在前,数字相同时,按字母进行排序,字母小的在前
        charList.sort((x, y) -> x.num != y.num ? y.num - x.num : x.ch - y.ch);

        StringBuilder sb = new StringBuilder();
        for (MyCharBean c : charList) {
            sb.append(c.toString());
        }

        System.out.println(sb);
    }

    /**
     * 字母出现的次数
     */
    static class MyCharBean {
        // 字母
        char ch;
        // 字母出现的次数
        int num;

        public MyCharBean(char ch, int num) {
            this.ch = ch;
            this.num = num;
        }

        /**
         * 按指定格式输出
         */
        @Override
        public String toString() {
            return this.ch + "" + this.num;
        }
    }
}

六、效果展示

1、输入

abcccbbaa

2、输出

c3a2a2b2b2

3、说明

abcccbbaa

  1. 第1个字符a,不连续,获取后面字符串中a的个数2 – a2;
  2. 第2个字符b,不连续,获取后面字符串中b的个数2 – b2;
  3. 第3个字符c,连续,一共3个 --c3;
  4. 第6个字符b,连续,一共2个 --b2;
  5. 第8个字符a,连续,一共2个 --a2;
  6. 变为a2b2c3b2a2;

输出c3a2a2b2b2

华为OD机试真题 Java 实现【字符串摘要】【2023 B卷 100分】,附详细解题思路-LMLPHP

4、再输入

abcccbbabaaccbca

5、输出

a4b4a3c3a2b2c2b1a0b0c0

6、说明

  1. 第一个字符a,不连续,后面字符串中a的个数为4,输出a4;
  2. 第二个字符b,不连续,后面字符串中b的个数为4,输出b4;
  3. 第三个字符c,连续3个,输出c3;
  4. 第6个字符b,连续2个,输出b2;
  5. 第8个字符a,不连续,后面字符串中a的个数为3,输出a3;
  6. 第9个字符b,不连续,后面字符串中b的个数为1,输出b1;
  7. 第10个字符a,连续2个,输出a2;
  8. 第12个字符c,连续2个,输出c2;
  9. 第14个字符b,不连续,后面没有b,输出b0;
  10. 第15个字符c,不连续,后面没有c,输出c0;
  11. 第16个字符a,不连续,后面没有a,输出a0;

a4b4c3b2a3b1a2c2b0c0a0

a4b4a3c3a2b2c2b1a0b0c0

这么复杂?其实思路很简单,不信,你亲自来验证一下?


🏆下一篇:华为OD机试真题 Java 实现【路灯照明问题】【2022Q4 100分】,感谢fly晨发现这个问题,并提供更优质的算法

🏆本文收录于,华为OD机试(JAVA)真题(A卷+B卷)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

华为OD机试真题 Java 实现【字符串摘要】【2023 B卷 100分】,附详细解题思路-LMLPHP

07-25 14:24