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

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

时间:2025-01-17 12:32:37浏览次数:3  
标签:解压 字符 java python 压缩 OD str error 字符串

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

题目

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

输入描述

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

输出描述

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

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

用例

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

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))  # 输出解压后的字符串或错误信息

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();  // 返回压缩后的字符串
    }
}

C++解法

  • 解题思路
更新中

C解法

  • 解题思路

更新中

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("");
}

注意:

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

标签:解压,字符,java,python,压缩,OD,str,error,字符串
From: https://blog.csdn.net/CodeClimb/article/details/145098997

相关文章

  • 基于javaweb的SpringBoot景区旅游管理系统设计和实现(源码+文档+部署讲解)
    个人名片......
  • Java编程思想第四版第十五章第8题(java中的一些基本概念)
    1.编程题目概况这是Java编程思想(第四版)第十五章中的编程作业题第8题,原文如下:练习8.模仿Coffee示例的样子,根据你喜爱的电影人物,创建一个StoryCharacters的类层次结构,将它们划分为GoodGuys和BadGuys.再按照CoffeeGenerator的形式,编写一个StoryCharacters的生成......
  • Sample Teamcenter SOA Java program : CreateOrUpdateBOMStructure
    SampleTeamcenterSOAJavaprogram:CreateOrUpdateBOMStructure  Solution/* This example was tested with the SOAJava HelloTeamcenter example provided in the soa_client.zip file.It assumes you have the HelloTeamcen......
  • 大数据学习记录,Java基础(6)
    集合Java集合框架体系Java集合可分为Collection和Map两种体系:Collection接口:单列数据,定义了存取一组对象的方法的集合List:元素有序、可重复的集合Set:元素无序、不可重复的集合Map接口:双列数据,保存具有映射关系“key-value对”的集合Collection接口的方法add......
  • 大数据学习记录,Java基础(5)
    常用类objectobject类是Java中所有类的共同父类Object类的方法1.toString()默认情况下,toString()返回的是“对象的运行时类型@对象的hashCode值的十六进制形式"如果我们直接System.out.println(对象),默认会自动调用这个对象的toString(),打印的是地址值可以根据需要在用......
  • 基于JAVA中的spring框架和jsp实现驾驶知识学习和评测系统项目【附项目源码+论文说明】
    摘要在21世纪这个信息高度发达,并且高速流通的时代,计算机的普及以及计算机网络技术的应用,让大量普通人能够有机会接触到比以往更多的知识。作为一个以传播知识为主要职能的机构——学校,建立一个自己的精品课程网站是十分必要的事情,这不仅能使更多的人享用宝贵的教育资料源,同时......
  • 大数据学习记录,Java基础(5)
    常用类objectobject类是Java中所有类的共同父类Object类的方法1.toString()默认情况下,toString()返回的是“对象的运行时类型@对象的hashCode值的十六进制形式"如果我们直接System.out.println(对象),默认会自动调用这个对象的toString(),打印的是地址值可以根据需要......
  • 大数据学习记录,Java基础(6)
    集合Java集合框架体系Java集合可分为Collection和Map两种体系:Collection接口:单列数据,定义了存取一组对象的方法的集合List:元素有序、可重复的集合Set:元素无序、不可重复的集合Map接口:双列数据,保存具有映射关系“key-value对”的集合Collection接口的方......
  • 基于JAVA中的spring框架和jsp实现大学生综合测评系统项目【内附项目源码+论文说明】
    摘要大学生综合测评系统是一款以大学生德智体等综合成绩进行评测的系统, 其开发基于B/S模式的网上评测的实现,采用的是JSP+sqlserver数据库为主要模式。在线评测平台是凌架于互联网系统上的一个评测平台,是地面评测系统的一种延伸和互补,也是实现无纸化评测的主要工具。当下在......
  • 2025毕设python在线小说阅读系统程序+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、选题背景关于在线小说阅读系统的研究,现有研究主要集中在系统的基本功能实现和用户体验优化方面,如一些商业在线阅读平台的开发与改进。专门针对......