题目:1084 外观数列 - PAT (Basic Level) Practice (中文) (pintia.cn)
题目分析:
第一项是
d
第二项是第一项的描述 d1,表示有1个d
第三项是对前两项的描述 d111,表示有1个d,1个1
第四项是对前三项的吗描述 d113,表示有1个d,3个1
……
递归版本
解析:PAT 1084 外观数列(20)(代码+思路+推荐测试用例) - 氵的博客 (cnblogs.com)
演示
起始
初始化: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(表示有2个1)
这个时候字符串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;
}
迭代版本
#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;
}