PAT.1078. 字符串压缩与解压 (20)(欢迎评论,讨论更有效率的算法)

该博客讨论了PAT考试中的字符串压缩和解压问题。对于给定的字符串,当输入字符为'C'时,需要将其压缩,例如'ccccc'变为'5c';当输入为'D'时,则进行解压,如'5c'恢复为'cccccc'。博客提供了压缩和解压的思路及处理方法,并给出了样例输入和输出。
摘要由CSDN通过智能技术生成

题目描述:
文本压缩有很多种方法,这里我们只考虑最简单的一种:把由相同字符组成的一个连续的片段用这个字符和片段中含有这个字符的个数来表示。例如 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

题目分析:其实这道题目思路还是蛮清晰的。
压缩:设置一个结构体数组存放所有被压缩的字符,结构体成员有存放字符的zimu,以及这个字符连续出现的次数count。再设置整型变量len记录当前被压缩的字符数目,读入字符串之后,先将第一个字母压进去,之后从第二个字母进行判断,如果和之前的字母一样,那么直接计数加一即可,如果不一样len++,压入新的字符。待处理完之后,就可以输出了,count=1的只输出字符,count>1的先输出该字符出现的数目再输出依次该字符(空格也不例外)。
解压: 这个对读入的字符串一个字符一个字符的判断,如果是字母那么直接输出即可,如果遇到了数字,需要判断下面几位是不是数字,要将所有的数字组成一个整数,然后for循环输出这些数字之后第一个字母。请看代码:

#include<stdio.h>
#include<string.h>
const int maxn=1000;
struct letter{
    char zimu;       //存放字母 
    int count;       //存放该字母连续出现的次数 
    letter(){
        count=0;
    }
}yasuo[maxn]; 
int len=0;    //用于存放当前已经被压缩的字符数量。 
bool judge(char a){              //解压函数需要用到它。 
    if((a>='a'&&a<='z')||(a>='A'&&a<='Z')||a==' '){    //判断是不是英文字母或者空格符 ,是就返回true。 
        return true;                 
    }
    return false;               //是数字返回false 
}
void yasuozifu(char str[]){              //压缩函数。 
    for(int i=1;i<strlen(str);i++){      //第一个字符已经被进入到yasuo[]中,后面的开始比较 
        if(str[i]==yasuo[len].zimu) {    //如果当前字符串的字符已经被添加到了压缩数组之中 ,计数加一 
            yasuo[len].count ++; 
        }
        else{
            len++;                        //如果还没有被添加到压缩数组中,那么将这个字符压缩进去 ,并计数 
            yasuo[len].zimu =str[i];
            yasuo[len].count++;       
        }
    }
    for(int i=0;i<=len;i++){            //压缩字符串的输出 
        if(yasuo[i].count!=1){
            printf("%d%c",yasuo[i].count,yasuo[i].zimu );
        }
        else{
            printf("%c",yasuo[i].zimu );    
        }       
    }
} 
void jieyazifu(char str[]){           //解压函数 
    for(int i=0;i<strlen(str);i++){    
        if(judge(str[i])){            //判断是数字还是字母 
            printf("%c",str[i]);      //如果是字母输出即可 
        }
        else {                        //如果是数字。 
            int temp=0;
            while(!judge(str[i])){    // 那么从开始的紧接着的所有数字组成整形数 
                temp=temp*10+(str[i]-'0');
                i++;
            }
            for(int j=0;j<temp;j++){    //输出相应个数的字母。 
                printf("%c",str[i]);
            }
        }
    } 
}
int main()
{
    char which,str[maxn];     //存放解压还是压缩命令字符的which 
    scanf("%c",&which);       //读入命令 
    getchar();           //吸收到上一行的换行符 ,使用gets的时候必定要注意的问题 
    gets(str);           //读入待操作字符串 
    //puts(str);
    if(which=='C'){     
        yasuo[len].zimu=str[0];  //先把第一个压缩进去 
        yasuo[len].count++; 
        yasuozifu(str);          //调用压缩函数 
    }
    else if(which=='D'){
        jieyazifu(str);          //调用解压函数 
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值