HDU
来源:互联网 发布:mac版cdr 编辑:程序博客网 时间:2024/06/01 08:46
展开字符串
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
题目大意:
按照给定的要求扩展并输出完整的字符串。
解题思路:
1.注意区分 x+(string) 和 x+ char 两种的区别。
2.采用了依次读取,每一段字符串,就是被()包围的一段作为一层,递归调用的方式打印复原。
具体方法看下面的函数:
int fun(int pos){ char c; int k,end; // k表示当前重复次数,end则记录进入下一层以后,下一层结束的位置 (注释见下) for(c=s[pos++] ; pos<strlen(s) && c!=')' ; c=s[pos++]){ //依次读取字符,直到当前层结束,或者到达字符串末尾 for(k=0;isdigit(c);c=s[pos++]){ k = k*10 + c-'0'; //数字可能不止一位数 } if(k==0) //注意()前 或 字母前没有数字都是是表示重复1次的 k=1; if(c=='('){ //读到'('进入下一层,打印k次括号内的字符串 while(k--) end = fun(pos); pos = end; //打印k次后再修正pos }else{ while(k--) //读到了字符,就打印相应次 putchar(c); } } if(c==')') //一层的结束,返回结束位置 return pos;}
其中 调用一次fun(int pos)函数,会打印从pos位置开始,到遇到’)’前的所有字符一次,并返回结束的位置。
注释: 例如 字符串0 数字x(字符串1)字符串2,到达 数字x 以后会进入下一层,调用fun自身打印字符串1,结束以后,pos的位置应该指向字符串1的结束位置后一个。并继续展开后续字符串。
源代码:
#include<iostream>#include<stdio.h>#include<cstring>#include<string.h>using namespace std;char s[255];int times;int fun(int pos){ char c; int k,end; for(c=s[pos++] ; pos<strlen(s) && c!=')' ; c=s[pos++]){ for(k=0;isdigit(c);c=s[pos++]){ k = k*10 + c-'0'; } if(k==0) k=1; if(c=='('){ while(k--) end = fun(pos); pos = end; }else{ while(k--) putchar(c); } } if(c==')') return pos;}int main(){ scanf("%d",×); for(int ti = 0;ti<times;ti++){ scanf("%s",s); fun(0); printf("\n"); } return 0;}