【练习】PAT 乙 1078 字符串压缩与解压

题目

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

来源:PAT 乙 1078 字符串压缩与解压


思路(注意事项)

压缩部分

  • 定义pre指向遍历元素的前一个元素,对比是否是同一个字符,
    • 如果是,则计数 + 1;
    • 如果不是,则准备输出
      • 如果计数不是1,则输出计数值再输出字符
      • 如果计数值为1,则直接输出字符
        注意更新计数值和前置值pre

解压部分

  • 需要定义一个nums字符串,用来记录解压的数字。
  • 如果遍历到数字,则累加到字符串nums
  • 如果遍历到非数字
    • 判断nums是否是空字符串
      • 如果是,直接输出当前字符
      • 如果不是,循环nums输出当前字符(需将nums转为int
      • 注意要重置nums
同时在压缩和解压过程都用到了n
  • 在压缩中的作用是:记录连续的字符需要压缩的字符数
  • 在解压中的作用是:用于记录在输出字符时,是否需要连续输出多个。
    • 如果n == 1,说明只输出一个字符
    • 如果n!= 1,说明需要连续输出多个
      在每次输出后需要置1,以便统计后续。

纯代码

#include
using namespace std;
int main(){
	char c;
	cin >> c;
	cin.ignore();
	string s;
	getline(cin, s);
    int n = 1;
	if (c == 'C'){
		char pre = s[0];
		for (int i = 1; i <= s.size(); i ++){
			if (s[i] == pre) n ++;
			else{
				if (n != 1) cout << n;
				cout << pre;
				n = 1;
				pre = s[i];
			}
		}
	}
	else{
        string nums;
		for (int i = 0; i <= s.size(); i ++){
            if(isdigit(s[i])) nums += s[i];
			else{
				if (nums != "") n = stoi(nums);
				while(n --) cout << s[i];
				n = 1;
                nums = "";
			}
		}
	}
	return 0;
} 

题解(加注释)

#include
using namespace std;

int main() {
    char c;
    cin >> c;  // 输入操作类型:'C' 表示压缩,'D' 表示解压
    cin.ignore();  // 忽略输入 c 后的换行符,避免影响后续的 getline 输入

    string s;
    getline(cin, s);  // 输入待处理字符串 s

    if (c == 'C') {  // 如果是压缩操作
        int n = 1;  // 用于记录连续相同字符的数量
        char pre = s[0];  // 记录前一个字符

        // 遍历字符串 s
        for (int i = 1; i <= s.size(); i ++) {
            if (s[i] == pre) {  // 如果当前字符与前一个字符相同
                n++;  // 增加计数
            } else {  // 如果当前字符与前一个字符不同
                if (n != 1) cout << n;  // 如果连续数量大于 1,输出数量
                cout << pre;  // 输出前一个字符
                n = 1;  // 重置计数
                pre = s[i];  // 更新前一个字符
            }
        }
    } else {  // 如果是解压操作
        string nums;  // 用于存储数字字符
        for (int i = 0; i <= s.size(); i ++) {  // 遍历字符串 s
            if (isdigit(s[i])) {  // 如果当前字符是数字
                nums += s[i];  // 将数字字符加入 nums
            } else {  // 如果当前字符不是数字
                if (nums != "") n = stoi(nums);  // 将 nums 转换为整数 n
                while (n --) cout << s[i];  // 输出当前字符 n 次
                n = 1;  // 重置 n
                nums = "";  // 清空 nums
            }
        }
    }

    return 0;
}

你可能感兴趣的:(输入输出,PAT,题解,有阻碍,算法,c++)