HDU1274 展开字符串

                                                          展开字符串

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 967    Accepted Submission(s): 416


Problem Description
在纺织CAD系统开发过程中,经常会遇到纱线排列的问题。
该问题的描述是这样的:常用纱线的品种一般不会超过25种,所以分别可以用小写字母表示不同的纱线,例如:abc表示三根纱线的排列;重复可以用数字和括号表示,例如:2(abc)表示abcabc;1(a)=1a表示a;2ab表示aab;如果括号前面没有表示重复的数字出现,则就可认为是1被省略了,如:cd(abc)=cd1(abc)=cdabc;这种表示方法非常简单紧凑,也易于理解;但是计算机却不能理解。为了使计算机接受,就必须将简单紧凑的表达方式展开。某ACM队接受了此项任务。现在你就是该ACM队的一员,请你把这个程序编写完成。
已知条件:输入的简单紧凑表达方式的长度不超过250个字符;括号前表示重复的数不超过1000;不会出现除了数字、括号、小写字母以外的任何其他字符;不会出现括号不配对等错误的情况(错误处理已由ACM其他队员完成了)。
 

Input
本题有多个测试数据组,第一行输入的就是数据组数N,接着就是N行表达式,表达式是按照前面介绍的意义书写的。
 

Output
输出时含有N行,每行对应一个输入的表达式。
 

Sample Input
   
   
   
   
2 1(1a2b1(ab)1c) 3(ab2(4ab))
 

Sample Output
   
   
   
   
abbabc abaaaabaaaababaaaabaaaababaaaabaaaab
 

Author
Cai Minglun
 

Source
杭电ACM集训队训练赛(VI)
 

Recommend
lcy

解题思路:本题可视为模拟题,难点在于去括号,可用栈存储括号信息以达到括号配对处理的目的。本题解题思维不难,阻碍在于需要耐心。

#include<stdio.h> #include<string.h> #include<stack> using namespace std; struct node //括号处理,存储节点 {     int i;  //括号后第一个字符在b数组中下标     int x;  //括号前的数字(处理结果) }; char a[252];    //存储原始字符串 char b[25002];      //存储去括号后字符串 char c[25002];      //存储处理完后的字符串(‘1’不处理) int made(int i,int &n)  //处理括号前的数字 {     int j,x=1;     n=0;     while(a[i-1]>='0'&&a[i-1]<='9')     {         n+=(a[i-1]-'0')*x;         x*=10;         i--;     }     return i; } int made2(int i,int &n)     //处理去括号后字符前的数字 {     int j,x=1;     n=0;     while(b[i-1]>='0'&&b[i-1]<='9')     {         n+=(b[i-1]-'0')*x;         x*=10;         i--;     }     return i; } int main() {     int t;     int n,str;     int i,j,k;     stack<node> s;     node next;     scanf("%d",&t);     while(t--)     {         scanf("%s",a);         str=strlen(a);         j=0;         //a数组-->b数组         for(i=0;i<str;i++)         {             if(a[i]=='(')   //遇到前括号,处理括号前数据,数据入栈             {                 int g=made(i,n);                 j=j-(i-g);//////退到括号前的第一个数字处,舍弃括号前面数字的存储信息                 next.i=j;                 next.x=n;                 s.push(next);             }             else if(a[i]==')')      //遇到后括号,最近的前括号信息节点出栈,数字按次数循环存储中间字母信息             {                 next=s.top();                 s.pop();                 int u;                 int o=j;                 for(k=1;k<next.x;k++)                 {                     for(u=next.i;u<o;u++)                         b[j++]=b[u];                 }             }             else    //一般字符,直接存储             {                 b[j++]=a[i];             }         }         //b数组-->c数组         k=0;         for(i=0;i<j;i++)         {             if(b[i]>='2'&&b[i]<='9')    //按字母前面数字进行循环存储             {                 while(b[i]>='0'&&b[i]<='9')                     i++;                 int x=made2(i,n);                 k=k-(i-x)+1;                 for(int u=0;u<n;u++)                     c[k++]=b[i];             }             else                 c[k++]=b[i];         }         for(i=0;i<k;i++)         {             if(c[i]!='1')                 printf("%c",c[i]);         }         puts("");     }     return 0; }




你可能感兴趣的:(C++,模拟)