HDU 1274

关于字符串处理的递归题,当然有的大神用栈做也能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其他队员完成了)。
 

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;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值