题目链接
题目大意:
给定一个压缩后的字符串,求其解压缩之后的长度。
两个存储的规则:
(1)如果字符串中有连续相同的大写字母,它们可以选择用”字符+出现次数”的方式替代。如字符串’AABCCCCDD’,可以用’A2BC4D2’表示,也可以用’A2BC2C2DD’表示。
(2)如果字符串中有连续出现的模式串(模式串长度大于1),它们可以选择用”(模式)+出现次数”的方式替代。如字符串’FABCABCABCE’,可以用’F(ABC)3E’表示,也可以用’F(ABC)2ABCE’表示。
上述规则中的”连续”均指出现次数大于1,规则(2)中的括号后一定是一个大于1的数值,代表出现次数。
综合上述两个规则,字符串’AABAABFAABAABFG’可以用’((A2B)2F)2G’表示。小Y保证输出的压缩串符合上述的两个规则,以下类型的非法字符串不会出现:
‘(A)5’: 括号冗余
‘A1A4’: 数字1冗余
‘A((AA))2’: 括号冗余
(ABC)1: 括号和数字1冗余
对于给定的一个用上述规则压缩后的字符串,对应的原串是唯一的。小Y想知道这个字符串原来的长度是多少,以此计算压缩倍率。你能帮助他吗?
样例:
样例输入
4
(AA)2A
((A2B)2)2G
WANGYI
A2BC4D2
样例输出
5
13
6
9
思路:
维护一个栈,
- 遇到 ‘(’ 将当前累计长度先压栈,
- 遇到 ‘)’则需要考虑其后面的
数字串
,将当前长度乘倍,并且将 栈顶元素出栈,累加到当前的长度上,- 遇到A-Z,将当前长度 +1
- 遇到数字,代表前一个字符乘倍
代码:
#include <iostream>
#include <fstream>
#include <stack>
using namespace std;
//fstream resource("/Users/bingoboy/Downloads/cases.txt");
int cnt;
string tmp;
stack<int> cstack;
char buf[110];
int main(){
int T;
cin>>T;
while(T--){
scanf("%s",buf);
int cur=0,mul=0;
stack<int> ntk;
for(int i=0;buf[i];){
if(buf[i]=='(') { // CASE 1
ntk.push(cur);
cur=0;mul=0;
i++;
}else if(buf[i]==')'){ // CASE 2
if(isdigit(buf[i+1])){
int j=i+1;
while(isdigit(buf[j])){
mul=mul*10 + buf[j]-'0';
j++;
}
cur*=mul; mul=0; // 当前长度乘倍
i=j;
}else{
i++;
}
cur+=ntk.top(); ntk.pop(); //栈顶元素出栈 ,累加到当前长度
}else if(isdigit(buf[i])){ // CASE 4
int j=i;
while(isdigit(buf[j])){
mul=mul*10 + buf[j]-'0';
j++;
}
cur+=mul-1; mul=0; //前一个字符乘倍
i=j;
}else{ //CASE3
cur++;
i++;
}
}
cout<<cur<<endl;
}
return 0;
}
/*
int parentheses(string & aa){
if (aa.empty()) {
return 0;
}
int fcnt = 0;
int amount = 0;
for (int i = 0; i < aa.size(); ++i) {
if (aa[i] == '(') {
cstack.push(fcnt);
fcnt = 0;
cstack.push(-1);
continue;
}
if (aa[i] == ')') {
++i;
while (aa[i] <= '9' && aa[i] >= '0') {
amount = amount*10 + aa[i] - '0';
i ++;
}
i--;
cstack.pop();
fcnt = amount * fcnt + cstack.top();
amount = 0;
cstack.pop();
continue;
}
while (aa[i] <= '9' && aa[i] >= '0') {
amount = amount*10 + aa[i] - '0';
i ++;
}
if (amount > 0) {
fcnt += amount - 1;
i --;
amount = 0;
continue;
}
fcnt += 1;
}
return fcnt;
}
int main(int argc, const char * argv[]) {
cin >> cnt;
while (cnt --) {
cin >> tmp;
cout << parentheses(tmp) << endl;
}
return 0;
}
*/
扫码关注作者,定期分享技术、算法类文章