HDU-1274 展开字符串 递归

OJ:https://cn.vjudge.net/problem/HDU-1274

 

题目没什么好说的,只有两个注意点 ab(ab) = ab1(ab) 数字不大于1000,也就是说数字可能不止一位。

 

解析:

要将给定的字符串进行展开,直接进行展开就可以了,只是要注意存在几种情况

1.当前字符是数字的时候,将当前的数字n计算出来,接下来又分两种情况

        1.数字后面直接跟的是一个字母,那么直接将后面的字母循环n次输出就可以了

        2.数字后面是一个括号,我们就要找出该左括号对应的右括号,然后将括号内的内容循环输出n次即可

2.当前字符是括号,当前直接出现括号,括号没有跟在数字后面,说明该括号内的内容输出一次即可

3.当前字符是数字,直接输出。

 

对于下面给出的代码,其实还有优化的空间,但是这个代码提交到oj上没有超时所以也就没有进行优化。

这里简单的讲解思路,代码中对于一个括号内重复输出n次,每次我们都是直接再次进行递归,其实可以将一次递归结果缓存起来,后面的n-1次就直接重复第一个递归的结果,就不用每次都去进行递归了。

 

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 300
int isDigit(char c);

int stack[MAX];
int size;

void solve(char *s,int ss,int end,int *kk){
    if(ss > end){
        return;
    }
    for(int i=ss;i<=end;i++){
        if(isDigit(s[i])){
            int n = 0;
            for(;i<=end;i++){
                if(isDigit(s[i])){
                    n = n * 10 + s[i] - '0';
                }else{
                    break;
                }
            }
            if(s[i] == '('){
                int e = kk[i];
                for(int k=0;k<n;k++){
                    solve(s,i+1,e-1,kk);
                }
                i = e;
            }else{
                for(int k=0;k<n;k++){
                    printf("%c",s[i]);
                }
            }
        }else if(s[i] == '('){
            int r = kk[i]-1;
            solve(s,i+1,r,kk);
            i = r+1;
        }else{
            printf("%c",s[i]);
        }
    }
}

// 栈
void push(int c){
    stack[size++] = c;
}

int pop(){
    return stack[--size];
}

int isDigit(char c){
    if(c >= '0' && c <= '9'){
        return 1;
    }
    return 0;
}

int main()
{
    int size=0;
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        char in[MAX];
        // 记录每一个左括号对应的右括号的下标
        int k[MAX];
        scanf("%s",in);
        int len = strlen(in);
        // 利用栈求出每一个左括号对应的右括号的位置
        for(int j=0;j<len;j++){
            if(in[j] == '('){
                push(j);
            }else if(in[j] == ')'){
                int l = pop();
                k[l] = j;
            }
        }
        solve(in,0,len-1,k);
        printf("\n");
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值