小Q想要给他的朋友发送一个神秘字符串,但是他发现字符串的过于长了, 于是小Q发明了一种压缩算法对字符串中重复的部分进行了压缩, 对于字符串中连续的m个相同字符串S将会压缩为[m|S](m为一个整数且1<=m<=100),例如字符串ABCABCABC将会被压缩为[3|ABC], 现在小Q的同学收到了小Q发送过来的字符串,你能帮助他进行解压缩么? 解题建议: (1)由于涉及到字符串的重复,尽量不要再使用C语言的字符数组,用C++的string类型会更容易实现。 (2)多层嵌套的情况,必须先求出内层再求出外层,显而易见可用递归算法或栈解决,建议递归。 (3)当确定s[i]是一个数字字符时,可以用如下C++代码获取字符串中的整数 int sum=0; while(isdigit(s[i])) sum=sum*10+s[i++]-'0';
输入格式
输入第一行包含一个字符串S,代表压缩后的字符串。 S的长度<=1000; S仅包含大写字母、[、]、|; 解压后的字符串长度不超过100000; 压缩递归层数不超过10层;
输出格式
输出一个字符串,代表解压后的字符串。
输入样例
HG[3|B[2|CA]]F
输出样例
HGBCACABCACABCACAF
递归写法:来自于oj标程
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
string s;
string dfs(int &l) /**< 递归处理第l个字符 */
{
int i,j,k,sum=0;
string ans="",temp="";
if(isdigit(s[l])) /**< 是数字,拿出完整值 */
{
while(isdigit(s[l]))
sum=sum*10+s[l++]-'0';
l++;
}
for(;l<s.size()&&s[l]!=']';l++)
{
if(s[l]=='[')
l++,ans+=dfs(l);
else
ans+=s[l];
}
if(sum==0) sum=1;
while(sum--) temp+=ans;
return temp;
}
int main()
{
int i=0;/**< 注意采用c++ &引用的方式使用这个i */
cin>>s;
cout<<dfs(i);
return 0;
}
栈写法:
#include<iostream>
#include<algorithm>
#include<sstream>
#include<math.h>
#include<vector>
#include<list>
#include<queue>
#include<set>
#include<map>
#include<string>
#include<stdio.h>
#include<ctype.h>
#include<cstring>
#include<cstdlib>
using namespace std;
list<string> a;//栈中字符
list<int> oprand;//操作数
list<char> oprator;//操作符
string relase(string s)
{
string s1;
for (int i = 0; i < s.length(); i++)
{
if (isalpha(s[i]) && oprator.empty())
{
s1 += s[i];
}
else if (isdigit(s[i]))
{
int sum = 0;
while (isdigit(s[i]))
sum = sum * 10 + s[i++] - '0';
oprand.push_back(sum);
i--;
}
else if (s[i]=='[')
{
oprator.push_back(s[i]);
}
else if (isalpha(s[i]))
{
string s2;
while(isalpha(s[i]))
s2 += s[i++];
a.push_back(s2);
i--;
}
else if (s[i] == ']')//遇到右括号时弹栈,算出当前压缩的字符
{
int n = oprand.back();
string s2 = a.back();
oprand.pop_back();
a.pop_back();
string s4 = s2;//用一个辅助字符串
for (int j = 1; j < n; j++)
{
s2 += s4;
}
if (a.size() >= 1)
{
string s3= a.back();
s3 += s2;
s2 = s3;
a.pop_back();
}
a.push_back(s2);
oprator.pop_back();
if (oprator.empty() && a.size() == 1)
{
s1 += a.back();
a.pop_back();
}
}
}
return s1;
}
int main()
{
//freopen("in.txt", "r", stdin);
string s;
cin >> s;
cout << relase(s);
}