PTA basic 1078 字符串压缩与解压 (20 分) c++语言实现(g++)
文本压缩有很多种方法,这里我们只考虑最简单的一种:把由相同字符组成的一个连续的片段用这个字符和片段中含有这个字符的个数来表示。例如 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
本题和 1077 1058 1073使用的方法几乎一致 在细节上的不同无非是 字符串中要截取的内容是什么
比如解压缩中, 要截取的是字符串中的数字,而压缩中截取的是重复的字符, 在程序的核心部分几乎相同
本题使用的方法是使用一个两个数组 一个记录每个字符出现按顺序 另一个记录这个字符的数量
在输出字符串的时候, 如果是解压缩就输出对应数量的字符
如果是压缩就先判定这个字符的数量是否大于1 是则输出数字, 否则跳过 , 然后输出字符
需要注意的一点是 压缩过程中, 循环比较的次数应该是str.size()+1 因为最后一个字符可能是和前面不同的字符,但是判定过程是出现不同的字符才压入数组,
而字符串的 第str.size()位置并不是非法地址, 是存放字符串结尾标记的'\0' 这个字符一定是字符串中没出现的换行字符 ,可以用来比较
#include <iostream> #include <vector> #include <string> using namespace std; void decompress(string &str,vector<char> &alpha,vector<int> &beta){//解压 表示多个相同字符的数字不一定是 个位数 //还是要遍历取出字符表 int count; char c; string temp; int left{0},right{0};//区别在于不用count计数, 出现的字母一定是单个字符不同的 当出现数字的时候需要取出数字字符串 //非数字直接推入字符数组,并在计数数组中推入1 while(left<str.size()){ c=str[left]; if(c>='0'&&c<='9'){//数字需要截取出来 count=0; right=left; while(right<str.size()){ if(str[right]<='9'&&str[right]>='0'){ count++; }else{//非数字时 temp=str.substr(left,count); beta.push_back(stoi(temp)); c=str[left+count];//取得数字之后的字符 alpha.push_back(c); break; } right++; } left=left+count+1;//跳过一个数字长度count和一个字符 }else{//遇到单个字符 直接推入数组 alpha.push_back(c); beta.push_back(1); left++; } } for(int i=0;i<alpha.size();i++){ for(int j=0;j<beta[i];j++){ printf("%c",alpha[i]); } } } void compress(string &str,vector<char> &alpha,vector<int> &beta){//压缩 int left{0},right{0},count{0}; char c; while(left<=str.size()){ c=str[left]; right=left; count=0;//因为right=left 所以str[right]=str[left]; count至少为1 while(right<=str.size()){//等于str.size()的时候 会遇到str的 \0 字符结束标志 和合法字符一定是不同的 if(str[right]==c){ count++; }else{ alpha.push_back(c); beta.push_back(count); break; } right++; } left=left+count; } for(int i=0;i<alpha.size();i++){ if(beta[i]>1){ printf("%d",beta[i]); } printf("%c",alpha[i]); } printf("\n"); } int main(){ char c; vector<char> alpha; vector<int> beta; vector<int> ss; string str; cin >> c; cin.ignore(); getline(cin, str); if(c=='D'){ decompress(str,alpha,beta); }else if(c=='C'){ compress(str,alpha,beta); } return 0; }