ZOJ 2240. Run Length Encoding

简介:     地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2240     题意:对一个给定字符串,按照下面的方式编码,输出结果。

    地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2240

    题意:对一个给定字符串,按照下面的方式编码,输出结果。

    (1)连续出现的数量在 2~9 个之间的字符,用两个字符表示。第一个字符表示数量(2~9),第二个是该字符。如果连续字符数量超过 9 个,先编码前 9 个字符,然后继续编码其余部分。

    (2)对于不包含连续字符的序列,先输出一个字符 1,然后是这个序列,然后结尾再追加一个字符 1。如果序列中包含字符 1,则在前面加一个转义字符 1,即输出连续两个 1。

 

    分析:粗看此题比较简单,线性扫描一次字符串即可。扫描过程涉及到状态转换,难度不大。但必须仔细阅读题目要求,因此需要很大的细心。我提交了 5 次才通过。主要是仔细审题。代码无须解释,严格按照题目要求的编码即可。只要通过基本测试即可。下面举几个典型的例子:

 

    aaaxyz -> 3a1xyz1

    aaa817 -> 3a181171

    aaaaaaaaaa -> 9a1a1

    11 -> 21

    1 -> 1111

    aaab -> 3a1b1

 

    下面是第 8 次提交的代码,主要变动是去掉了不必要的用于存储“不重复字符序列”的辅助空间,和一些细微调整(发现不重复序列的截止点时,直接转入重复序列状态,而不是未知状态。发现重复序列的截止点时,必须进入未知状态,因为下一个状态取决于 p[2] 和 p[1] 的关系)。把循环体内的 if - else if 改成了 switch 语句,以让逻辑更清楚。

 

zoj2240_code
#include <stdio.h>

#define UNKNOW    0    /* 未知状态 */
#define SUBSTR    1    /* 处于 不重复字符序列 中 */
#define REPEAT    2    /* 处于 重复字符序列 中 */

/* 输出不重复字符序列中的一个字符,1 需要转义 */
void put_one_char(char c)
{
    if(c == '1') printf("11");
    else putchar(c);
}

void encode(char* text)
{
    char* p = text;
    int status = UNKNOW;
    int count; /* 重复字符序列长度 */
    while(*p)
    {
        switch(status)
        {
        case UNKNOW: /* 检测当前所处状态 */
            if(p[1] != p[0])
            {
                status = SUBSTR;
                printf("1"); /* 前缀 1 */
                put_one_char(*p);
            }
            else
            {
                status = REPEAT;
                count = 1;
            }
            break;

        case SUBSTR: /* 位于 不重复字符序列 中 */
            if(p[1] != p[0])
            {
                put_one_char(*p);
            }
            else
            {
                printf("1"); /* 后缀 1 */
                status = REPEAT;
                count = 1;
            }
            break;

        case REPEAT: /* 位于 重复字符序列 中 */
            count++;
            if(count == 9 || p[1] != p[0])
            {
                printf("%d%c", count, *p);
                status = UNKNOW;
            }
            break;
        }
        ++p;
    }

    /* 重要:如果以不重复字符序列结束,循环结束后输出后缀 1 */
    if(status == SUBSTR) printf("1");
}

int main(int argc, char* argv[])
{
    char line[1024];
    while(gets(line) != NULL)
    {
        encode(line);
        printf("\n");
    }
    return 0;
}

 

    encode 函数中,由于前两个 case 的代码比较接近,因此可以把前两个 case 合并到一起,使代码更紧凑,但可读性可能有所降低。代码如下:

 

code_encode_v2
void encode(char* text)
{
    char* p = text;
    int status = UNKNOW;
    int count; /* 重复字符序列长度 */
    while(*p)
    {
        switch(status)
        {
        case UNKNOW: /* 检测当前所处状态 */
        case SUBSTR: /* 位于 不重复字符序列 中 */
            if(p[1] != p[0])
            {
                if(status == UNKNOW)
                {
                    status = SUBSTR;
                    printf("1"); /* 前缀 1 */
                }
                put_one_char(*p);
            }
            else
            {
                if(status == SUBSTR) printf("1"); /* 后缀 1 */
                status = REPEAT;
                count = 1;
            }
            break;

        case REPEAT: /* 位于 重复字符序列 中 */
            count++;
            if(count == 9 || p[1] != p[0])
            {
                printf("%d%c", count, *p);
                status = UNKNOW;
            }
            break;
        }
        ++p;
    }

    /* 重要:如果以不重复字符序列结束,循环结束后输出后缀 1 */
    if(status == SUBSTR) printf("1");
}

 

    代码中需要注意的几点:

    (1)如果是连续出现的字符1,是不需要转义的,因为这时的 1 不会有歧义。例如“111” 被编码为“31”,而不是“311”。

    (2)如果字符串以不重复序列结束,则不要遗忘输出后缀 1。遇到字符串结尾时,循环结束,但序列可能尚未输出完成!这仅存在于字符串的最后一个字符和倒数第二个字符不同的情况(如果相同,则属于连续字符序列,在循环结束之前已经输出了)。

目录
相关文章
看见“信任”,可信计算史上最全解析
等保2.0将可信提升到一个新的强度。在等保一到四级都有可信的要求,主要在三个领域:计算环境可信、网络可信、接入可信。
看见“信任”,可信计算史上最全解析
西门子S7-1200程序状态监视,监视表格的使用方法,如何使用交叉引用列表
本篇我们来学习西门子S7-1200程序状态监视、监视表格、交叉引用的使用方法。
西门子S7-1200程序状态监视,监视表格的使用方法,如何使用交叉引用列表
|
10月前
|
人工智能 自动驾驶 安全
《解锁数据新动能:数据标注工具与AI模型训练平台的无缝对接热潮》
在人工智能快速发展的今天,数据成为核心驱动力。数据标注工具与模型训练平台的集成,实现了数据无缝流转,犹如为AI发展装上双引擎。集成不仅提高了数据传输效率、减少了人工干预,还确保了数据准确性,提升了模型性能。统一的数据标准、高效的接口设计和严格的安全保障是实现无缝流转的关键要素。这种集成推动了医疗、自动驾驶等领域的快速发展,促进了数据驱动的创新,为企业和社会带来巨大价值。未来,这一趋势将更加高效智能,进一步推动AI技术的广泛应用。
354 8
|
弹性计算 网络安全 数据安全/隐私保护
如何将本地文件上传至阿里云ECS中
利用WinSCP与云服务器ECS实现文件互通
17628 1
|
安全 网络安全
IP的纯净度:评判标准与重要性
**IP纯净度关乎网络行为的安全与可靠性。高纯净度IP指独立、真实、无不良记录的地址。评估标准包括:** - **IP来源**:正规ISP的IP更纯净。 - **历史记录**:检查是否涉及违规行为或在黑名单中。 - **技术特征**:支持SSL,匿名性高,连接稳定快速的IP更佳。 - **用户反馈**:用户评价反映IP的实际表现和信誉。 综合考量这些因素,能确保选择到安全可靠的IP地址。
|
开发者 iOS开发 C#
Uno Platform 入门超详细指南:从零开始教你打造兼容 Web、Windows、iOS 和 Android 的跨平台应用,轻松掌握 XAML 与 C# 开发技巧,快速上手示例代码助你迈出第一步
【8月更文挑战第31天】Uno Platform 是一个基于 Microsoft .NET 的开源框架,支持使用 C# 和 XAML 构建跨平台应用,适用于 Web(WebAssembly)、Windows、Linux、macOS、iOS 和 Android。它允许开发者共享几乎全部的业务逻辑和 UI 代码,同时保持原生性能。选择 Uno Platform 可以统一开发体验,减少代码重复,降低开发成本。安装时需先配置好 Visual Studio 或 Visual Studio for Mac,并通过 NuGet 或官网下载工具包。
1569 0
|
网络协议
IPv6 私有地址
IPv6 私有地址
2268 0
IPv6 私有地址
|
人工智能 监控 算法
西门子S7-200 SMART PID回路控制,如何配置PID向导、调用子程序?如何创建状态图表测试程序?如何自整定PID参数?
PID控制器是应用最广泛的闭环控制器,它根据给定值与被控变量实测值之间的偏差,按照PID算法计算出控制器的输出量控制执行机构进行调节,使被控量跟随给定量进行变化并使系统达到稳定,自动消除各种干扰对控制过程的影响,其中P、I、D分别指比例、积分、微分。
西门子S7-200 SMART PID回路控制,如何配置PID向导、调用子程序?如何创建状态图表测试程序?如何自整定PID参数?
|
SQL 存储 人工智能
华为高斯认证(opengauss)HCIA
华为高斯认证(opengauss)HCIA
2905 0