华为OD机试真题---一种字符串压缩表示的解压

华为OD机试真题中,有一种关于字符串压缩表示的解压题目,其具体要求和相关解析如下:

一、题目描述

有一种简易压缩算法:针对全部由小写英文字母组成的字符串,将其中连续超过两个相同字母的部分压缩为连续个数加该字母,其他部分保持原样不变。例如,字符串“aaabbccccd”经过压缩成为字符串“3abb4cd”。
现在需要编写解压函数,根据输入的字符串,判断其是否为合法压缩过的字符串。若输入合法,则输出解压缩后的字符串;否则,输出字符串“!error”来报告错误。

二、输入描述

输入一行,为一个ASCII字符串,长度不超过100字符。用例保证输出的字符串长度也不会超过100字符。

三、输出描述

  • 若判断输入为合法的经过压缩后的字符串,则输出压缩前的字符串。
  • 若输入不合法,则输出字符串“!error”。

四、示例

输入
4dff
输出
ddddff

说明:4d扩展为dddd,故解压后的字符串为“ddddff”。

输入
2dff
输出
!error

说明:两个d不需要压缩,故输入不合法。

五、 解题思路

  1. 校验输入字符串是否合法:
合法与不合法的判定
  • 合法:只有小写字母和数字组成,且数字必须大于2,数字后紧跟着字母。

  • 不合法

    • 数字小于等于2;

    • 数字后没有字母;

    • 有两个以上连续的相同字符(这种已经是压缩过的形式);

    • 出现非小写字母和非数字字符(例如特殊字符@和大写字母A等)。

    • 首先检查字符串是否只包含小写字母和数字。

    • 然后遍历字符串,检查数字是否大于2,数字后是否紧跟着字母,以及是否有连续的非法格式(如两个以上连续的相同字符,或数字后直接跟数字等)。

  1. 如果输入字符串合法,则进行解压操作:

    • 遍历字符串,当遇到数字时,将后面的字母按照数字指定的次数重复拼接起来。
    • 如果遇到字母,则直接添加到结果字符串中。
  2. 如果输入字符串不合法,则输出“!error”。

六、代码实现(Python示例)

def check(input_str):
    # 检查字符串是否只包含小写字母和数字
    if not input_str.isalnum():
        return False

    i = 0
    while i < len(input_str):
        c = input_str[i]
        if c.isdigit():
            num = int(c)
            # 数字必须大于2
            if num <= 2:
                return False
            # 数字后必须跟着字母
            if i + 1 >= len(input_str) or not input_str[i + 1].isalpha():
                return False
            # 检查后续是否有非法格式(如连续相同字母的非法压缩)
            next_char = input_str[i + 1]
            j = i + 2
            while j < len(input_str) and input_str[j] != next_char:
                # 如果遇到相同字母前的数字,则是非法格式
                if input_str[j].isdigit():
                    return False
                j += 1
            # 如果j没有跳出循环,说明有连续相同字母的非法压缩
            if j < len(input_str) and input_str[j] == next_char:
                return False
            i += 2  # 跳过数字和紧跟的字母
        else:
            # 检查是否有三个或更多连续相同的字母
            if i + 2 < len(input_str) and input_str[i] == input_str[i + 1] == input_str[i + 2]:
                return False
            i += 1
    return True

def decompress(input_str):
    builder = []
    i = 0
    while i < len(input_str):
        c = input_str[i]
        if c.isdigit():
            num = int(c)
            if i + 1 < len(input_str):
                letter = input_str[i + 1]
                builder.append(letter * num)
                i += 2  # 跳过数字和紧跟的字母
            else:
                # 数字后没有字母,非法(但在check中已经处理,这里不会到达)
                return "!error"
        else:
            builder.append(c)
            i += 1
    return ''.join(builder)

def main():
    input_str = input().strip()
    if not check(input_str):
        print("!error")
    else:
        print(decompress(input_str))

if __name__ == "__main__":
    main()

七、代码实现(java示例)

import java.util.Scanner;
public class StringDecompressor {

    /**
     * 检查输入的字符串是否为有效的压缩字符串
     * 压缩字符串的定义规则如下:
     * - 字符串中只能包含小写字母和数字
     * - 数字必须大于2,并且必须紧接一个小写字母
     * - 不能有连续相同的字母,除非它们被数字压缩
     * - 不能有连续的数字
     *
     * @param input 待检查的字符串
     * @return 如果字符串是有效的压缩字符串,则返回true;否则返回false
     */
    public static boolean isValidCompressedString(String input) {
        // 空字符串或null不是有效的压缩字符串
        if (input == null || input.isEmpty()) {
            return false;
        }

        // 遍历字符串中的每个字符
        for (int i = 0; i < input.length(); i++) {
            char currentChar = input.charAt(i);

            // 如果当前字符是数字
            if (Character.isDigit(currentChar)) {
                int num = Character.getNumericValue(currentChar);

                // 数字必须大于2
                if (num <= 2) {
                    return false;
                }

                // 检查数字后是否紧跟着字母
                if (i + 1 >= input.length() || !Character.isLowerCase(input.charAt(i + 1))) {
                    return false;
                }

                // 检查后续字符是否合法(避免连续相同字符的非法压缩形式)
                char nextChar = input.charAt(i + 1);
                if (i + 2 < input.length() && input.charAt(i + 2) == nextChar) {
                    // 如果数字后紧跟相同字母,检查是否再次被压缩(即是否有连续的数字)
                    if (Character.isDigit(input.charAt(i + 2))) {
                        return false;
                    }
                    // 否则,继续检查后续字符,确保没有连续相同字母(这已经是压缩形式)
                    for (int j = i + 2; j < input.length(); j++) {
                        if (input.charAt(j) == nextChar) {
                            return false;
                        }
                    }
                }

                // 跳过紧跟在数字后的字母,因为后续逻辑会处理它
                i++;

            } else if (!Character.isLowerCase(currentChar)) {
                // 字符串中只能包含小写字母和数字
                return false;
            }
        }

        // 如果所有检查都通过,则字符串是有效的压缩字符串
        return true;
    }

    /**
     * 解压缩字符串中的数字和字母
     * 对于输入字符串中的每个数字n,如果其后紧跟着一个字母,则将该字母重复n次添加到结果字符串中
     * 如果字符不是数字,则直接添加到结果字符串中
     *
     * @param input 要解压缩的字符串,包含数字和小写字母
     * @return 解压缩后的字符串
     */
    public static String decompressString(String input) {
        StringBuilder result = new StringBuilder();

        for (int i = 0; i < input.length(); i++) {
            char currentChar = input.charAt(i);

            // 检查当前字符是否为数字
            if (Character.isDigit(currentChar)) {
                int num = Character.getNumericValue(currentChar);

                // 数字后必须紧跟着字母
                if (i + 1 < input.length() && Character.isLowerCase(input.charAt(i + 1))) {
                    char letter = input.charAt(i + 1);
                    for (int j = 0; j < num; j++) {
                        result.append(letter);
                    }
                    i++; // 跳过紧跟在数字后的字母
                }

            } else {
                // 直接添加字母到结果中
                result.append(currentChar);
            }
        }

        return result.toString();
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine().trim();
        scanner.close();

        if (isValidCompressedString(input)) {
            System.out.println(decompressString(input));
        } else {
            System.out.println("!error");
        }
    }
}

八、运行实例解析

1. 调用 isValidCompressedString 方法

输入字符串 4dff 将被传递给 isValidCompressedString 方法进行验证。

  • 首先,检查输入字符串是否为 null 或空字符串。4dff 不是 null 也不是空字符串,因此继续。
  • 遍历字符串中的每个字符:
    • i = 0:当前字符是 '4',是数字。
      • 数字 4 大于 2,符合条件。
      • 检查 '4' 后是否紧跟着小写字母:下一个字符是 'd',是小写字母,符合条件。
      • 检查后续字符是否合法:跳过 'd',后续字符是 'f''f',但 'f' 不是 'd' 的重复,且 'f' 后没有数字,因此这里不会返回 false
      • 跳过紧跟在数字后的字母 'd',将 i 增加到 1
    • i = 1:当前字符是 'd',是小写字母,直接跳过。
    • i = 2:当前字符是 'f',是小写字母,直接跳过。
    • i = 3:当前字符是 'f',是小写字母,直接跳过。
  • 所有检查都通过,字符串 4dff 是有效的压缩字符串。
2. 调用 decompressString 方法

输入字符串 4dff 将被传递给 decompressString 方法进行解压缩。

  • 创建一个 StringBuilder 对象 result 用于构建解压缩后的字符串。
  • 遍历字符串中的每个字符:
    • i = 0:当前字符是 '4',是数字。
      • 数字 4 后紧跟着小写字母 'd'
      • 'd' 重复 4 次添加到 result 中:result 现在是 "dddd"
      • 跳过紧跟在数字后的字母 'd',将 i 增加到 1
    • i = 1:当前字符是 'f',不是数字,直接添加到 result 中:result 现在是 "ddddf"
    • i = 2:当前字符是 'f',不是数字,直接添加到 result 中:result 现在是 "ddddff"
  • 遍历结束,返回 result.toString(),即解压缩后的字符串 "ddddff"
最终输出

程序输出解压缩后的字符串 ddddff

九、注意事项

  • 在校验字符串时,要仔细检查各种不合法的情况,确保输入字符串符合压缩算法的要求。
  • 在解压过程中,要注意正确处理数字和其后面的字母,避免索引越界或重复添加字符等问题。

以上即为华为OD机试中关于字符串压缩表示的解压题目的详细介绍、解题思路以及代码实现示例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值