题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1274
因为压缩串的特征,可以将问题规模不断缩少,而处理步骤却是一样的,所以可以用递归解决它。
其中有两种基本串,可以直接输出:
- 由单个a-z字母组成的串;
- 由重复次数+单个a-z字母组成的串;
其他的串都被认为是复合串,复合串可以通过提取括号内容,将问题化解为重复子问题若干遍:
- 括号包裹的串;(括号内容作为子问题,重复次数为1)
- 重复次数+括号包裹的串;(括号内容作为子问题,重复次数由括号左侧的重复次数决定)
除以上两条规则外,还有最后一条规则,那就是基本串或复合串可以从左向右任意串连。
依据以上思路所编写的代码如下:
#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;
}