1078 字符串压缩与解压(PAT (Basic Level) Practice)

题目

文本压缩有很多种方法,这里我们只考虑最简单的一种:把由相同字符组成的一个连续的片段用这个字符和片段中含有这个字符的个数来表示。例如 ccccc 就用 5c 来表示。如果字符没有重复,就原样输出。例如 aba 压缩后仍然是 aba

解压方法就是反过来,把形如 5c 这样的表示恢复为 ccccc

本题需要你根据压缩或解压的要求,对给定字符串进行处理。这里我们简单地假设原始字符串是完全由英文字母和空格组成的非空字符串。

输入格式:

输入第一行给出一个字符,如果是 C 就表示下面的字符串需要被压缩;如果是 D 就表示下面的字符串需要被解压。第二行给出需要被压缩或解压的不超过 1000 个字符的字符串,以回车结尾。题目保证字符重复个数在整型范围内,且输出文件不超过 1MB。

输出格式:

根据要求压缩或解压字符串,并在一行中输出结果。

输入样例 1:

C
TTTTThhiiiis isssss a   tesssst CAaaa as

输出样例 1:

5T2h4is i5s a3 te4st CA3a as

输入样例 2:

D
5T2h4is i5s a3 te4st CA3a as10Z

输出样例 2:

TTTTThhiiiis isssss a   tesssst CAaaa asZZZZZZZZZZ

通过代码(极致压行版)

#include <iostream>
#include <ctype.h>
using namespace std;
void Cprint(int& count, char a) {//注意count是引用变量
    if (count != 1) cout << count;
    cout << a;
    count = 0;
}
int main () {
    string str, c;
    int i = 0, count = 1;//i是解码的循环变量,控制下标。count是压缩过程中记录重复字符出现次数的
    getline(cin, c); getline(cin, str);//输入
    if (c == "C") {
        for (int j = 1; j < str.length(); j++, count++)//每次循环count++
            if (str[j - 1] != str[j]) Cprint(count, str[j - 1]);//如果遇到一个字符和前一个不一样,输出,让count归零
        Cprint(count, str[str.length() - 1]);//输出最末尾的一个或一串
    } else if (c == "D") {
        if (!isdigit(str[i])) cout << str[i++];//第一个不是数字,直接输出,i++访问下一个字符
        for (int n = 0; i < str.length(); n = 0, i++) {//n为每个字符前的数字
            for (; i < str.length() && isdigit(str[i]); n *= 10, n += (str[i++] - '0'));//如果是数字,就把数字字符转换成数,这里不是双层for循环嵌套,这个for循环后有一个分号
            for (int j = 0; j < (n == 0 ? 1 : n); j++) cout << str[i];//循环输出字符,如果没有遇到数字,n为0,就输出一次
        }
    }
    return 0;
}

通过代码

#include <iostream>
#include <algorithm>
#include <ctype.h>
using namespace std;
struct out { char c; int n; };
void C () {
    string str;
    getline(cin, str);
    int n = str.length();
    out data[n] = {0};
    char last = -1;
    int count = -1;
    for (int i = 0; i < n; i++) {
        if (str[i] != last)
            data[++count].c = str[i];
        data[count].n++;
        last = str[i];
    }
    for (int i = 0; i < count + 1; i++) {
        if (data[i].n != 1)
            cout << data[i].n;
        cout << data[i].c;
    }
}
void D () {
    string str;
    getline(cin, str);
    int i = 0;
    if (!isdigit(str[i]))
        cout << str[i++];
    while (i < str.length()) {
        int n = 0;
        while (i < str.length() && isdigit(str[i])) {
            n *= 10;
            n += str[i++] - '0';
        }
        for (int j = 0; j < n; j++)
            cout << str[i];
        i++;
        while ( i < str.length() && !isdigit(str[i]))
            cout << str[i++];
    }
}
int main () {
    char c;
    scanf("%c%*c", &c);
    if (c == 'C') C();
    else D();
    return 0;
}

思路与注意

  1. coding(压缩)一个函数,decoding(解压)一个函数分别处理

  2. 两个函数统一使用getline,main函数里面要吃掉第一行的换行符

  3. 对于coding过程

    1. 定义一个结构体数组,储存字符与个数。数组长度为输入string的长度(如果输入的string不能压缩,正好够用)

    2. 遍历一遍string,如果字符和前一个字符一样,那么当前结构体(变量)的字符个数++,一旦改变,存到下一个结构体中。

    3. 输出结构体,先输出个数(大于1才输出),再输出这个字符

  4. 对于decoding过程

    1. 先判断第一个字符,如果是字母直接输出这个字母,然后字符串的“指针”向后移。

    2. 进入循环,循环的操作为,得到数字,输出数字后的字母,然后输出后面的单个字母,直到遇到下一个数字,进入下一次循环,或者遇到字符串结束,那就结束。

    3. 注意不要用isalpha()函数(考虑空格的存在)

反思与评价

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容