【LintCode】Expression Expand

题目描述


Given an expression s includes numbers, letters and brackets. Number represents the number of repetitions inside the brackets(can be a string or another expression).Please expand expression to be a string.

测试数据


s = abc3[a] return abcaaa
s = 3[abc] return abcabcabc
s = 4[ac]dy, return acacacacdy
s = 3[2[ad]3[pf]]xyz, return adadpfpfpfadadpfpfpfadadpfpfpfxyz

解题思路


很明显运算过程中具有嵌套的性质,需要使用栈来解决,又因为问题可分解,即将一个大的字符串看做S = C + (N[S])* + C,其中C表示常量字符串,即在本层次不需要扩展的字符串,N表示数字,S表示待处理的字符串,*表示后面的部分可以多次出现。这样我们就可以通过递归来解决。

在使用递归的时候,对于C部分,直接加到结果中就行,问题在于中间的部分,即N[S]可能会出现多次,因此需要使用一个大循环,在循环中再递归。

另外,由于使用C语言实现,而C中并没有字符串这种数据类型,在返回结果的时候如果返回指针也不可以,因为函数返回的时候auto变量会被释放,所以需要自己定义一个字符串类型用于返回。

最后一个问题是对于原始字符串的遍历,需要在多层次的递归函数中保持指针位置的统一,所以使用了二重指针,这样就可以让不同层次的函数使用同一个指针进行操作。

C实现代码


#include <stdio.h>

typedef struct string
{
    char data[100];
    int length;
} string;

string expression_expand(char **src)
{
    int num = 0;
    string single, repeat;//single表示未重复的字符串,repeat表示已经重复处理的字符串
    single.length = 0;
    repeat.length = 0;

    while(**src != '\0')
    {
        //首先将字符串中无需重复的部分取出
        while(**src >= 'a' && **src <= 'z' && **src != '\0')
        {
            repeat.data[repeat.length++] = **src;
            (*src)++;
        }
        //如果是数字,将数字提取出来
        while(**src >= '0' && **src <= '9' && **src != '\0')
        {
            num *= 10;
            num += **src - '0';
            (*src)++;
        }
        //如果遇到'[',把后面字符串的重复工作交给下次递归处理
        if(**src == '[')
        {
            (*src)++;
            single = expression_expand(src);
        }
        //当获得数字后面的字符串的处理结果之后,
        //由本次递归对整个结果进行重复处理
        while(num != 0)
        {
            num--;
            int i;
            for(i = 0; i < single.length; i++)
            {
                repeat.data[repeat.length++] = single.data[i];
            }
        }
        //如果遇到']',说明待重复的字符串已经提取完毕,返回给上层递归
        if(**src == ']')
        {
            (*src)++;
            return repeat;
        }

    }
    return repeat;
}


int main(int argc, char *argv[])
{
    char data[100];
    char *point;
    while(~scanf("%s", data))
    {
        point = data;
        string ret = expression_expand(&point);
        ret.data[ret.length] = '\0';
        printf("%s\n", ret.data);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值