每日一题(三):压缩字符串(行程长度编码)

目录

一、题目

科普部分(题目背景)

[Run-length encoding(行程长度编码)](#Run-length encoding(行程长度编码))

二、题目分析

(一)明确需求

(二)分析思路

三、将思路转换为程序

C++代码

C代码

四、总结


一、题目

实现一个算法来压缩字符串。压缩要求如下:

1.需要判断压缩是否能够节省空间,仅在压缩后的字符串比原字符串短时进行压缩。

2.压缩的格式是将连续相同字符替换为字符 + 数字形式,例如 "AAABCCDDDD" 变为 "A3BC2D4"。

输入描述:

输入一行,表示要压缩的字符串,长度不超过500。字符串中一次性重复字符不超过9个。

输出描述:

输出一行。若输入的字符串可压缩,则输出压缩后的字符串,否则输出 NO。

科普部分(题目背景)

在讲这道题之前,博主先进行一个知识科普:

Run-length encoding(行程长度编码)

行程长度编码是一种用于压缩字符串中某一些重复一遍又一遍的长字符序列。大体意思便是,用重复的字符加上重复数替代一长串有序的重复的字符。为了表明或者是指示这些经过行程长度编码进行处理的字符串,我们会在它们的开头加上一个提示符号(flag)。例如:一部分DNA的序列是"GGGGGAAAAAACCCCC"。使用行程长度编码和提示符号(flag)"#",它可以表示为"#G5#A6#C5"。

通过对行程长度编码的介绍,我想大家都看出来了,本次的题目的本质就是对行程长度编码的使用和扩展。 唯一不同的便是本题没有加上提示符号。

二、题目分析

(一)明确需求

根据题目要求,我们需要设计一个算法来实现对字符串的压缩。需要特别注意的是题目要求中说了要对压缩是否能够节省空间进行判断。也就是说一次性重复字符数至少要超过2,才能进行压缩。

其次根据描述,我们这次需要设置一个大小为500的字符数组来接收输入数据,为了便于输出我们也需要使用同样大小的字符数组进行输出。(通过增加部分空间复杂度,来提升时间复杂度)

(二)分析思路

为了解决这一问题,对于要进行压缩的字符数组,我们可以使用两个变量a、b来标识数组下标,a代表的下标指向第一个重复的字符,b代表的下标从该位置开始向前遍历,每遍历到一个重复字符,进行一次计数。如果遍历到的是不同的字符,则令a=b。同时在另一个字符数组中记录相应信息。

那么我们因该如何进行记录呢?根据计数值来进行判断,如果用count变量来代表字符重复的个数,首先我们将可能重复的字符放入字符数组,然后按上面形式进行遍历,最终当count为1时代表只有一个字符,这时不用管;当count为2时代表有两个一样的字符,则在下一个位置重复记录上一字符(代表不需要压缩,因为不能减少空间);当count大于2时,则将下一个位置记录为重复的个数。

三、将思路转换为程序

使用C与C++模拟实现:

C++代码

cpp 复制代码
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
    char str1[500] = { 0 };
    char str2[500] = { 0 };
    cin >> str1;
    int len1 = strlen(str1);
    int x = 0;
    int a = 0;
    int b = 0;
    while (a <= len1)
    {
        int count = 0;
        while (str1[b] == str1[a])
        {
            b++;
            count++;
        }
        str2[x++] = str1[a];
        if (count > 2)
        {
            str2[x++] = count + '0';
        }
        else if (count == 2)
        {
            str2[x++] = str1[a];
        }
        a = b;
    }
    int len2 = strlen(str2);
    if (len1 == len2)
    {
        cout << "NO";
    }
    else
    {
        cout << str2;
    }
    return 0;
}

C代码

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    char str1[500] = { 0 };
    char str2[500] = { 0 };
    scanf("%s", str1);
    int len1 = strlen(str1);
    int x = 0;
    int a = 0;
    int b = 0;
    while (a <= len1)
    {
        int count = 0;
        while (str1[b] == str1[a])
        {
            b++;
            count++;
        }
        str2[x++] = str1[a];
        if (count > 2)
        {
            str2[x++] = count + '0';
        }
        else if (count == 2)
        {
            str2[x++] = str1[a];
        }
        a = b;
    }
    int len2 = strlen(str2);
    if (len1 == len2)
    {
        printf("NO");
    }
    else
    {
        printf("%s", str2);
    }
    return 0;
}

四、总结

本篇博客讲解了使用"行程长度编码"的方式进行字符串压缩的分析和思考过程,想必大家对这种题型有了更深刻的了解与思考。每日一题,让今天变为更好的自己。

如果觉得博主写得不错,可以点点赞和收藏吧!如果期待博主的下一次博客就给博主点个关注吧!

如有问题可随时斧正,如有疑惑可随时讨论。

相关推荐
自信的小螺丝钉5 分钟前
Leetcode 279. 完全平方数 动态规划 完全背包问题
算法·leetcode·动态规划
努力的泽泽9 分钟前
【动态规划-矩阵】5.下降路径最小和
算法·矩阵·动态规划
埃菲尔铁塔_CV算法3 小时前
双线性插值算法:原理、实现、优化及在图像处理和多领域中的广泛应用与发展趋势(二)
c++·人工智能·算法·机器学习·计算机视觉
叫我龙翔3 小时前
【算法日记】从零开始认识动态规划(一)
c++·算法·动态规划·代理模式
AC100AC3 小时前
[NOIP2007 提高组] 矩阵取数游戏
算法·游戏·矩阵
深度混淆3 小时前
C#,图论与图算法,输出无向图“欧拉路径”的弗勒里(Fleury Algorithm)算法和源程序
算法·图论
大草原的小灰灰3 小时前
C++ STL之容器介绍(vector、list、set、map)
数据结构·c++·算法
小刘|4 小时前
数据结构的插入与删除
java·数据结构·算法
w(゚Д゚)w吓洗宝宝了5 小时前
List详解 - 双向链表的操作
数据结构·c++·链表·list
廖显东-ShirDon 讲编程5 小时前
《零基础Go语言算法实战》【题目 2-22】Go 调度器优先调度问题
算法·程序员·go语言·web编程·go web