HDOJ1274展开字符串

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1274

因为压缩串的特征,可以将问题规模不断缩少,而处理步骤却是一样的,所以可以用递归解决它。

其中有两种基本串,可以直接输出:

  1. 由单个a-z字母组成的串;
  2. 由重复次数+单个a-z字母组成的串;

其他的串都被认为是复合串,复合串可以通过提取括号内容,将问题化解为重复子问题若干遍:

  1. 括号包裹的串;(括号内容作为子问题,重复次数为1)
  2. 重复次数+括号包裹的串;(括号内容作为子问题,重复次数由括号左侧的重复次数决定)

除以上两条规则外,还有最后一条规则,那就是基本串或复合串可以从左向右任意串连。

依据以上思路所编写的代码如下:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
char g_input[251];
int read_integer(int start, int *length)
{
    int result = 0;
    int i = start;
    while (isdigit(g_input[i]))
    {
        result = result * 10 + (g_input[i] - '0');
        i++;
    }
    *length = i - start;
    return result;
}
int parenthesis_length(int start)
{
    int level = 1;
    int i = start + 1;
    while (level > 0)
    {
        char current = g_input[i];
        if (current == '(')
        {
            level++;
        }
        else if (current == ')')
        {
            level--;
        }
        i++;
    }
    return i - start;
}
void expand(int times, int start, int length)
{
    while (times-- > 0)
    {
        int i = 0;
        int len;
        while (i < length)
        {
            char current = g_input[start + i];
            if (isdigit(current))
            {
                int sub_times = read_integer(start + i, &len);
                i += len;
                char next = g_input[start + i];
                if (next == '(')
                {
                    len = parenthesis_length(start + i);
                    expand(sub_times, start + i + 1, len - 2);
                    i += len;
                }
                else
                {
                    // must be basic character,like a,b,c...z
                    while (sub_times-- > 0)
                    {
                        putchar(next);
                    }
                    i++;
                }
            }
            else if (current == '(')
            {
                len = parenthesis_length(start + i);
                expand(1, start + i + 1, len - 2);
                i += len;
            }
            else
            {
                // muse be basic character, like a,b,c,...z
                putchar(current);
                i++;
            }
        }
    }
}
int main(void)
{
    int testCase;
    scanf("%d", &testCase);
    while (testCase-- > 0)
    {
        scanf("%s", g_input);
        expand(1, 0, strlen(g_input));
        putchar('\n');
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值