
目录
- 专栏导读
- 一、题目描述
- 二、输入描述
- 三、输出描述
- 四、解题思路
- 1、题意
- 2、根据题意,不合法方式如下:
- 3、解题思路
 
- 五、Java算法源码
- 六、效果展示
- 1、输入
- 2、输出
 
 
华为OD机试 2023B卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷)》。
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
有一种简易压缩算法:针对全部由小写英文字母组成的字符串,将其中连续超过两个相同字母的部分压缩为连续个数加该字母,其他部分保持原样不变。
例如:字符串“aaabbccccd”经过压缩成为字符串“3abb4cd”。
请您编写解压函数,根据输入的字符串,判断其是否为合法压缩过的字符串,若输入合法则输出解压缩后的字符串,否则输出字符串“!error” 来报告错误。
二、输入描述
输入一行,为一个ASCII字符串,长度不会超过100字符,用例保证输出的字符串长度也不会超过100字符。
三、输出描述
若判断输入为合法的经过压缩后的字符串,则输出压缩前的字符串;
 若输入不合法,则输出字符串“!error” 。
| 输入 | 输出 | 说明 | 
|---|---|---|
| 4dff | ddddff | 4d扩展为dddd,故解压后的字符串为ddddff。 | 
| 2dff | !error | 两个d不需要压缩,故输入不合法。 | 
| 4d@A | !error | 全部由小写英文字母组成的字符串压缩后不会出现特殊字符@和大写字母A,故输入不合法。 | 
四、解题思路
1、题意
针对全部由小写英文字母组成的字符串,将其中连续超过两个相同字母的部分压缩为连续个数加该字母,其他部分保持原样不变。
若判断输入为合法的经过压缩后的字符串,则输出压缩前的字符串;
若输入不合法,则输出字符串“!error” 。
2、根据题意,不合法方式如下:
- 只有数字和小写字母组成;
- 数字后紧跟着字母;
- 连续超过两个相同字母的部分才压缩,即数字必须大于2;
- 如果有两个以上连续的相同字符,也是非法的,因为这种已经压缩了;
- 4dd和4d3d这两种情况也是违法的;
3、解题思路
- 先对输入字符串进行check,校验字符串时合法的,再进行按题意解压。
- 定义一个StringBuilder,拼接压缩前的字符串;
- 如果是数字; 
  - 将数字后的字母拼接c个到builder;
- 注意:如果此处使用Integer.valueOf或者int强转,会将c转为48+c
 
- 不是数字,直接拼接;
- 输出压缩前的字符串。
五、Java算法源码
package com.guor.od;
import java.util.*;
public class OdTest02 {
    /**
     * 针对全部由小写英文字母组成的字符串,将其中连续超过两个相同字母的部分压缩为连续个数加该字母,其他部分保持原样不变。
     * <p>
     * 若判断输入为合法的经过压缩后的字符串,则输出压缩前的字符串;
     * 若输入不合法,则输出字符串“!error” 。
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String input = sc.nextLine();
        if (!check(input)) {
            System.out.println("!error");
            return;
        }
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            // 如果是数字
            if (Character.isDigit(c)) {
                /**
                 * 将数字后的字母拼接c个到builder
                 * 注意:如果此处使用Integer.valueOf或者int强转,会将c转为48+c
                 */
                for (int j = 0; j < Character.getNumericValue(c) - 1; j++) {
                    builder.append(input.charAt(i + 1));
                }
            } else {
                // 不是数字,直接拼接
                builder.append(c);
            }
        }
        System.out.println(builder);
    }
    /**
     * 针对全部由小写英文字母组成的字符串,将其中连续超过两个相同字母的部分压缩为连续个数加该字母,其他部分保持原样不变。
     * <p>
     * 根据题意,不合法方式:
     * 1. 只有数字和小写字母组成
     * 2. 数字后紧跟着字母
     * 3. 连续超过两个相同字母的部分才压缩,即数字必须大于2
     * 4. 如果有两个以上连续的相同字符,也是非法的,因为这种已经压缩了
     * 5. 4dd和4d3d这两种情况也是违法的
     */
    private static boolean check(String str) {
        // 1. 只有数字和小写字母组成
        if (!str.matches("^[a-z0-9]+$")) {
            return false;
        }
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            // 2. 数字后紧跟着字母
            if (Character.isDigit(c)) {
                // 3. 数字必须大于2
                if (Character.getNumericValue(c) <= 2) {
                    return false;
                }
                if (i < str.length() - 1) {
                    char next = str.charAt(i + 1);
                    // 如果下一位还是数字
                    if (Character.isDigit(str.charAt(i + 1))) {
                        return false;
                    } else {
                        // 4dd时,也是非法的
                        if (i < str.length() - 2) {
                            char next2 = str.charAt(i + 2);
                            // 4d3d时,也是非法的
                            if (Character.isDigit(next2)) {
                                if (i < str.length() - 3) {
                                    if (next == str.charAt(i + 3)) {
                                        return false;
                                    }
                                }
                            } else {
                                // 4dd时,也是非法的
                                if (next == next2) {
                                    return false;
                                }
                            }
                        }
                    }
                } else if (i == str.length() - 1) {// 如果最后一位是数字,也是非法的
                    return false;
                }
            } else {
                // 如果后面还有大于两个字符,则有可能三连相同字符
                if (i < str.length() - 3) {
                    if (c == str.charAt(i + 1) && c == str.charAt(i + 2)) {
                        return false;
                    }
                }
            }
        }
        return true;
    }
}
六、效果展示
1、输入
3d4f5dss3a
2、输出
dddffffdddddssaaa

🏆下一篇:华为OD机试真题 Java 实现【简易内存池】【2023 B卷 200分 考生抽中题】
🏆本文收录于,华为OD机试(JAVA)真题(A卷+B卷)
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。




















