PAT1084 外观数列 20分 知识点:压缩字符串

94 阅读2分钟

题目:1084 外观数列 - PAT (Basic Level) Practice (中文) (pintia.cn)

题目分析:

image.png 第一项是 d

第二项是第一项的描述 d1,表示有1个d

第三项是对前两项的描述 d111,表示有1个d,1个1

第四项是对前三项的吗描述 d113,表示有1个d,3个1

……



递归版本

解析:PAT 1084 外观数列(20)(代码+思路+推荐测试用例) - 氵的博客 (cnblogs.com) image.png

演示

起始

初始化:d=1(假设传1)  cs="" s="1"

if判断s[i]==s[i+1],因为s只要一个元素,所以肯定不想等
进入else语句:
cs+=s[i],cs="1"

然后cs+=count,此时cs="11";

然后就下一重循环了

判断 s[i]==s[i+1],1=1,所以count++,此时count=2(表示有21)
这个时候字符串s遍历完了,结束循环,进入递归。

第一次递归

此时 s="11" cs=""(每次递归都被置为空),count=1(每次递归都被置为1)

s[i]=s[i+1]=1,count++,count=2

进行下一层循环
比较s[i]==s[i+1],因为s只有两个字符"11",现在下标i指向的第二个1,那么i+1实际上越界了,肯定不可能相等,直接到else 语句了

cs+=s[i]="1"
cs+=count="12"

循环结束,进入第二层递归,以此类推
#include <iostream>
#include<string>
using namespace std;
string compress(string s, int n) {
	if (n == 1)		//直到n=1时,不需要压缩
		return s;
	string cs;		//压缩字符串
	int count = 1;
	for (int i = 0; i < s.length(); i++) {
		if (s[i] == s[i + 1])	//与后一个进行比较
			count++;
		else {
			cs += s[i];
			cs += to_string(count);
			count = 1;
		}
	}
	s = cs;
	return compress(s, n - 1);		//递归再压缩一次
}
int main() {
	string str;
	int n;
	cin >> str >> n;
	cout << compress(str, n);;
	return 0;
}

迭代版本

解析:84_哔哩哔哩_bilibili

#include<iostream>
#include<cstring>
#include<string>

using namespace std;

int main()
{
    string s, temp;
    int n;//第n项是对第n-1项的描述,第n项已经给了,因此我们只用枚举到第n-1项即可
    cin >> s >> n;
    for (int i = 1; i <= n - 1; i++)
    {
        int t = 1;  //重置
        for (int j = 0; j < s.size(); j++)
        {
            while (s[j] == s[j + 1])j++, t++;  //如果前一项和后一项一样那么就进行压缩,t++代表相同的字符的个数,j++是为了走出while循环,

            temp += s[j] + to_string(t);
            t = 1;
        }
        s = temp; //更新字符串
        temp.clear(); //清空
    }

    cout << s;
    return 0;
}