已知条件:输入的简单紧凑表达方式的长度不超过250个字符;括号前表示重复的数不超过1000;不会出现除了数字、括号、小写字母以外的任何其他字符;不会出现括号不配对等错误的情况(错误处理已由ACM其他队员完成了)。
本题有多个测试数据组,第一行输入的就是数据组数N,接着就是N行表达式,表达式是按照前面介绍的意义书写的。
输出时含有N行,每行对应一个输入的表达式。
3(ab2(4ab))
abaaaabaaaababaaaabaaaababaaaabaaaab
这是一道递归的题目,抠的挺细的感觉,
要多注意题干,我刚开始交了,没看到 cd(abc)=cdabc
结果WA一次,下次看题真要仔细了。
方法当然是递归了,
刚开始分情况:
①碰到数字
②碰到字符
③碰到括号(左括号或者右括号)
碰到数字,也有可能是多位数字,比如12a,
我就用的就是一个变量,sz, 当遇到数字,sz=str[i]-‘0‘+sz*10
这样多少位都不怕了(当然要在整型范围内哈),
碰到字符,我是判断前一个(就是str[i-1])是不是数字,
如果是数字,那就在主串上加上,重复的相应字符,
如果不是数字,那就代表是1,直接加上这个字符就行了
碰到左括号,当然递归,这里有一点注意,括号内情况有多种:
1. 2(ab)
2. (ab)
3. (2ab)
4. (a2b)
5. (2ab3(..))
这几种情况,都要考虑一下,尤其是,碰到括号前如果不是数字。
我遇到括号,先判断括号前一个数字,是不是数字,如果不是数字,
那就将sz变量设置为1,这样当括号回来(递归结束),可以循环一次。
碰到右括号,右括号注意事项不多,一般,我的主函数中遇到就直接跳过,
递归函数遇到就return,
仔细一点,就很容易AC了。
代码:
#include <iostream>
#include <string>
using namespace std;
// str,len,i 都是全局变量
string str;
int len,i;
string tobracket(void)
{
// str1 辅助串
int j,sz=0;
string str1="";
for(;i<len;++i)
{
// 遇到数字
if(str[i]>=‘0‘ && str[i]<=‘9‘)
{
sz=str[i]-‘0‘+sz*10;
}
// 遇到字符
else if(str[i]>=‘a‘ && str[i]<=‘z‘)
{
if(str[i-1]>=‘0‘ && str[i-1]<=‘9‘)
{
for(j=0;j<sz;++j)
str1+=str[i];
sz=0;
continue;
}
str1+=str[i];
}
// 遇到左括号
else if(str[i]==‘(‘)
{
if(str[i-1]>=‘a‘ && str[i]<=‘z‘) sz=1;
++i;
string str_bt=tobracket();
for(j=0;j<sz;++j)
str1+=str_bt;
sz=0;
}
// 遇到右括号
else
return str1;
}
}
int main()
{
string str_final;
int j,n,sz;
cin>>n;
while(n--)
{
cin>>str;
len=str.length();
sz=0;
str_final="";
for(i=0;i<len;++i)
{
// 遇到数字
if(str[i]>=‘0‘ && str[i] <=‘9‘)
{
sz=str[i]-‘0‘+sz*10;
}
// 遇到字符
else if(str[i]>=‘a‘ && str[i]<=‘z‘)
{
if(str[i-1]>=‘0‘ && str[i-1] <=‘9‘)
{
for(j=0;j<sz;++j)
str_final+=str[i];
sz=0;
continue;
}
str_final+=str[i];
}
// 遇到左括号
else if(str[i]==‘(‘)
{
if(str[i-1]>=‘a‘ && str[i]<=‘z‘) sz=1;
++i;
string str_bt=tobracket();
for(j=0;j<sz;++j)
str_final+=str_bt;
sz=0;
}
}
cout<<str_final<<endl;
}
return 0;
}ACM-递归之展开字符串——hdu1274,布布扣,bubuko.com
原文:http://blog.csdn.net/lttree/article/details/20792517