首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

【华为OD-E卷 -73 一种字符串压缩表示的解压 100分(python、java、c++、js、c)】

  • 25-03-07 19:22
  • 3085
  • 6817
blog.csdn.net

【华为OD-E卷 - 一种字符串压缩表示的解压 100分(python、java、c++、js、c)】

题目

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

输入描述

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

输出描述

  • 若判断输入为合法的经过压缩后的字符串,则输出压缩前的字符串;

若输入不合法,则输出字符串“​**!error**​”

用例

用例一:
输入:
4dff
  • 1
输出:
ddddff
  • 1
用例二:
输入:
2dff
  • 1
输出:
!error
  • 1
用例三:
输入:
4d@A
  • 1
输出:
!error
  • 1

python解法

  • 解题思路:
  • 这段代码的目标是实现对一个压缩字符串的解压操作。输入的压缩字符串满足以下条件:

字符串是由字母和数字组成,数字表示前面字母的重复次数。
解压后的字符串需要符合原压缩规则。
具体步骤如下:

输入字符串的合法性检查:首先判断字符串中是否含有非小写字母和数字的字符,如果有则直接返回 !error。
解压过程:遍历压缩字符串,如果遇到数字,则认为它表示后一个字符的重复次数,根据数字展开字符;如果数字无效(如小于等于2,或后面没有字母),返回 !error。
压缩验证:解压后的字符串如果经过压缩后不再得到原始的压缩字符串,说明解压有问题,返回 !error。
返回解压后的字符串:如果解压顺利且验证通过,返回解压后的字符串

import re

def decompress_string(input_string):
    # 使用正则表达式检查字符串中是否包含非小写字母和数字的字符
    if re.search(r"[^a-z0-9]", input_string):
        return "!error"  # 如果包含其他字符,返回错误
    
    result = []  # 用来存储解压后的结果
    i = 0  # 遍历输入字符串的指针
    while i < len(input_string):
        if input_string[i].isdigit():  # 如果当前字符是数字
            count = int(input_string[i])  # 获取数字值,表示下一个字母的重复次数
            if count <= 2 or i + 1 >= len(input_string) or not input_string[i + 1].isalpha():
                # 如果数字小于等于2,或者数字后面不是字母,或者没有字母,说明格式错误
                return "!error"
            result.append(input_string[i + 1] * count)  # 重复字母并添加到结果列表
            i += 2  # 跳过数字和字母
        else:
            result.append(input_string[i])  # 如果当前是字母,直接添加到结果列表
            i += 1  # 移动到下一个字符

    # 解压后的字符串进行再次压缩,如果压缩后的结果不等于原始输入,说明解压有误
    if compress("".join(result)) != input_string:
        return "!error"
    
    return "".join(result)  # 返回解压后的字符串

def compress(text):
    compressed = []  # 用来存储压缩后的结果
    i = 0  # 遍历字符串的指针
    while i < len(text):
        count = 1  # 初始化重复次数为1
        while i + 1 < len(text) and text[i] == text[i + 1]:  # 找到连续相同的字符
            count += 1  # 计数器加1
            i += 1  # 指针移动到下一个字符
        if count > 2:  # 如果字符重复次数大于2,进行压缩
            compressed.append(f"{count}{text[i]}")  # 添加压缩后的格式 "数量+字符"
        else:  # 否则将字符按原样添加
            compressed.extend([text[i]] * count)
        i += 1  # 移动到下一个不同的字符
    return "".join(compressed)  # 返回压缩后的字符串

# 测试部分
s = input()
print(decompress_string(s))  # 输出解压后的字符串或错误信息

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

java解法

  • 解题思路
  • 该程序的目标是处理一个压缩格式的字符串,并对其进行解压缩操作,解压的结果要符合特定的规则,若不符合要求,则返回 !error。

合法性检查: 首先检查字符串是否只包含小写字母和数字。如果包含其他字符,则返回 !error。

正则表达式匹配: 使用正则表达式 (\d+)([a-z]) 来查找所有数字和字母的组合。数字代表后面字母的重复次数,如果数字小于等于2或者格式不对,返回 !error。

解压缩: 将匹配到的数字和字母按照规则展开,将字母按数字指定的次数重复。

压缩验证: 解压后的字符串要经过压缩操作,如果压缩后的结果不等于原始的输入字符串,则说明解压过程有误,返回 !error。

返回解压后的字符串: 如果解压和验证都通过,则返回解压后的字符串

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String input = scanner.nextLine();  // 读取输入的字符串
        System.out.println(getResult(input));  // 输出解压结果或错误信息
    }

    // 主要的解压函数
    public static String getResult(String str) {
        String originalStr = str;  // 保存原始的输入字符串,用于后续验证

        // 如果输入字符串包含非小写字母或数字的字符,则返回错误
        if (!str.matches("[a-z0-9]*")) {
            return "!error";
        }

        // 正则表达式匹配,寻找数字和字母的组合
        Pattern regExp = Pattern.compile("(\\d+)([a-z])");
        Matcher matcher = regExp.matcher(str);

        // 逐个匹配数字和字母的组合
        while (matcher.find()) {
            String match = matcher.group();  // 获取匹配的字符串
            int repeatTimes = Integer.parseInt(matcher.group(1));  // 获取数字部分,即字母重复的次数
            char character = matcher.group(2).charAt(0);  // 获取字母部分

            // 如果数字小于等于2,则返回错误
            if (repeatTimes <= 2) {
                return "!error";
            }

            // 扩展字母,重复指定的次数
            String expanded = String.valueOf(character).repeat(repeatTimes);
            // 替换原字符串中的数字和字母组合为扩展后的字符串
            str = str.replace(match, expanded);
        }

        // 进行压缩验证,检查解压后的字符串是否能还原为原始输入字符串
        if (!zip(str).equals(originalStr)) {
            return "!error";
        }

        return str;  // 返回解压后的字符串
    }

    // 压缩函数:将解压后的字符串进行压缩
    public static String zip(String str) {
        StringBuilder compressed = new StringBuilder();  // 用于构建压缩后的字符串
        int i = 0;  // 遍历字符串的指针

        // 遍历字符串,压缩相同的字符
        while (i < str.length()) {
            int count = 1;  // 初始化字符的重复次数为1

            // 找到连续重复的字符
            while (i + 1 < str.length() && str.charAt(i) == str.charAt(i + 1)) {
                count++;  // 计数器加1
                i++;  // 移动指针
            }

            // 如果字符的重复次数大于2,则压缩为 "数量+字符" 的形式
            if (count > 2) {
                compressed.append(count).append(str.charAt(i));
            } else {
                // 否则将字符按原样添加
                compressed.append(String.valueOf(str.charAt(i)).repeat(count));
            }

            i++;  // 移动到下一个不同的字符
        }

        return compressed.toString();  // 返回压缩后的字符串
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

C++解法

  • 解题思路
更新中
  • 1

C解法

  • 解题思路

更新中
  • 1

JS解法

  • 解题思路

  • 这段代码的目标是解压一个压缩格式的字符串,并对其进行检查和验证。如果压缩字符串的格式不正确,则返回 !error。如果格式正确,则返回解压后的字符串。

具体步骤如下:

合法性检查:

输入字符串必须只包含小写字母(a-z)和数字(0-9)。如果包含其他字符,立即返回 !error。
正则表达式匹配:

使用正则表达式 (\d+)([a-z]) 来查找所有数字和字母的组合。数字表示字母的重复次数,字母是要被重复的字符。
每次匹配到的数字需要满足重复次数大于2。如果数字小于等于2,则返回 !error。
对每个匹配项,将数字指定的字符重复相应的次数,并替换原字符串中的匹配部分。
解压完成后的压缩验证:

对解压后的字符串执行压缩操作(即通过 zip 函数)。如果压缩后的字符串和原始输入字符串不一致,说明解压过程出现了错误,返回 !error。
返回解压后的字符串:

如果解压和验证都成功,则返回解压后的字符串

const readline = require("readline");

// 创建接口以读取标准输入
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

// 监听每一行输入,处理并输出结果
rl.on("line", (line) => {
    console.log(getResult(line));  // 输出处理结果
});

// 主函数:处理解压逻辑
function getResult(str) {
    const originalStr = str;  // 保存原始输入,用于后续验证

    // 如果输入字符串包含非小写字母或数字的字符,直接返回错误
    if (/[^a-z0-9]/.test(str)) {
        return "!error";
    }

    // 正则表达式匹配:查找数字+字母的组合
    const regExp = /(\d+)([a-z])/g;

    // 持续处理所有匹配的数字和字母组合
    while (true) {
        const match = regExp.exec(str);  // 查找下一个匹配项

        if (!match) break;  // 如果没有更多匹配项,则退出循环

        // 解构匹配结果:src为匹配的整个字符串,repeatTimesStr为数字部分,char为字母部分
        const [src, repeatTimesStr, char] = match;
        const repeatTimes = parseInt(repeatTimesStr, 10);  // 将数字部分转为整数

        // 如果数字小于等于2,表示格式不合法,返回错误
        if (repeatTimes <= 2) {
            return "!error";
        }

        // 扩展字母部分,按照重复次数进行重复
        const expanded = char.repeat(repeatTimes);
        // 替换原字符串中的数字和字母组合为展开后的字母部分
        str = str.replace(src, expanded);
    }

    // 完成解压后,对解压结果进行压缩验证
    if (zip(str) !== originalStr) {
        return "!error";  // 如果压缩结果不匹配原始输入,说明解压错误
    }

    return str;  // 返回解压后的字符串
}

// 压缩函数:将解压后的字符串进行压缩
function zip(str) {
    let compressed = [];  // 用来存储压缩后的字符
    let i = 0;  // 字符串遍历指针

    // 遍历字符串并压缩连续相同的字符
    while (i < str.length) {
        let count = 1;  // 初始化连续字符的计数为1

        // 查找连续相同的字符
        while (i + 1 < str.length && str[i] === str[i + 1]) {
            count++;  // 计数器加1
            i++;  // 移动指针
        }

        // 如果字符的重复次数大于2,则压缩成 "数量+字符" 的形式
        if (count > 2) {
            compressed.push(`${count}${str[i]}`);
        } else {
            // 否则直接将字符按原样添加
            compressed.push(str[i].repeat(count));
        }

        i++;  // 移动到下一个不同的字符
    }

    // 返回压缩后的字符串
    return compressed.join("");
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

注:本文转载自blog.csdn.net的CodeClimb的文章"https://blog.csdn.net/CodeClimb/article/details/145098997"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top