【LintCode】Expression Expand

来源:互联网 发布:js文件 syntax error 编辑:程序博客网 时间:2024/06/10 12:44

题目描述


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 abcaaas = 3[abc] return abcabcabcs = 4[ac]dy, return acacacacdys = 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;}