关于字符串处理的递归题,当然有的大神用栈做也能ac
展开字符串
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2170 Accepted Submission(s): 1047
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其他队员完成了)。
该问题的描述是这样的:常用纱线的品种一般不会超过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、get数字;2、去括号输出
我是这么想的,例如输入一个字符串str ,定义两个函数分别是Output(int n, int left, int right),和get_num(int index)分别用来输出(left,right)(开区间)里的内容和get要输出的次数。因为每个括号都是一个同样的问题只是括号的位置不同,那么我一开始可以调用Output(1,-1,strlen(str))意思就是把(-1,len)这个区间里的字符串输出一次。然后遍历输出或者处理括号就可以ac,不过千万记得括号的匹配要考虑各种情况不然很容易出问题!对 我就这么wa了一发,懵逼了好半天不知道是为什么,最后实在搞不定了就去网上找题解但是也懒得看,所幸第一篇题解就给了你测试数据,正好测出了我括号匹配有问题。下面贴代码(代码一是错误代码,也就是括号匹配有问题的代码,代码二是ac的)。
/*
* test.cpp
*
* Created on: 2016年3月12日
* Author: Triose
*/
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<map>
#include<set>
using namespace std;
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define inf 0x3f3f3f3f
#define rep(i,a) for((i)=0; i<(a);(i)++)
#define mem(a,b) (memset((a),b,sizeof(a)))
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sfs(a) scanf("%s",a)
#define pf(a) printf("%d\n",a)
#define pfs(a) printf("%s\n",a)
#define pfI(a) printf("%I64d\n",a)
#define LL __int64
const double PI = acos(-1.0);
template<class T> T gcd(T a, T b) { return b ? gcd(b, a%b) : a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b)*b; }
template<class T> inline T Min(T a, T b) { return a<b ? a : b; }
template<class T> inline T Max(T a, T b) { return a>b ? a : b; }
int n, m;
#define N 260
char str[N];
int s,e;
int get_num(int& index) {
int num = 0;
while(str[index] <= '9' && str[index] >= '0') {
num = num * 10 + (str[index++] - '0');
}
return num;
}
void Output(int times, int left, int right) {
int next_times = 0;
for(int t = 0; t < times; t++) {
s = left;
e = right;
for(int i = left + 1; i < right; i++) {
if(str[i] <= '9' && str[i] >= '0') {
next_times = get_num(i);
if(str[i] != '(') {
for(int j = 0; j < next_times ; j++) {
putchar(str[i]);
}
}
else {
s = i;<span style="white-space:pre"> </span>//这里的括号匹配有问题,并不是所有的括号都是镶嵌着的,可能有平级的
e--;
while(str[e] != ')') {
e--;
}
i = e;
Output(next_times, s, e);
}
}
else if(str[i] <= 'z' && str[i] >= 'a') {
putchar(str[i]);
}
else {
continue;
}
}
}
}
int main() {
int t;
sf(t);
while(t--) {
sfs(str);
s = -1; e = strlen(str);
Output(1,s,e);
putchar(10);
}
return 0;
}
ac代码:
/*
* test.cpp
*
* Created on: 2016年3月12日
* Author: Triose
*/
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<iterator>
#include<math.h>
#include<stdlib.h>
#include<map>
#include<set>
using namespace std;
//#define ONLINE_JUDGE
#define eps 1e-8
#define INF 0x7fffffff
#define inf 0x3f3f3f3f
#define rep(i,a) for((i)=0; i<(a);(i)++)
#define mem(a,b) (memset((a),b,sizeof(a)))
#define sf(a) scanf("%d",&a)
#define sfI(a) scanf("%I64d",&a)
#define sfd(a,b) scanf("%d%d",&a,&b)
#define sft(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sfs(a) scanf("%s",a)
#define pf(a) printf("%d\n",a)
#define pfs(a) printf("%s\n",a)
#define pfI(a) printf("%I64d\n",a)
#define LL __int64
const double PI = acos(-1.0);
template<class T> T gcd(T a, T b) { return b ? gcd(b, a%b) : a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b)*b; }
template<class T> inline T Min(T a, T b) { return a<b ? a : b; }
template<class T> inline T Max(T a, T b) { return a>b ? a : b; }
int n, m;
#define N 260
char str[N];
int s,e;
int get_num(int& index) {
int num = 0;
while(str[index] <= '9' && str[index] >= '0') {
num = num * 10 + (str[index++] - '0');
}
return num;
}
void Output(int times, int left, int right) {
int next_times = 0;
for(int t = 0; t < times; t++) {
s = left;
e = right;
for(int i = left + 1; i < right; i++) {
if(str[i] <= '9' && str[i] >= '0') {
next_times = get_num(i);
if(str[i] != '(') {
for(int j = 0; j < next_times ; j++) {
putchar(str[i]);
}
}
else {
s = i;
// e--;
// while(str[e] != ')') {
// e--;
// }
int flag = 1;<span style="white-space:pre"> </span>//对 ,我就这样想了个蠢办法搞定了
for(e = s + 1; ; e++) {
if(str[e] == '(')
flag++;
if(str[e] == ')')
flag--;
if(str[e] == ')' && flag == 0)
break;
}
i = e;
Output(next_times, s, e);
}
}
else if(str[i] <= 'z' && str[i] >= 'a') {
putchar(str[i]);
}
else {
continue;
}
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
// freopen("Out.txt", "w", stdout);
#endif
int t;
sf(t);
while(t--) {
sfs(str);
s = -1; e = strlen(str);
Output(1,s,e);
putchar(10);
}
return 0;
}