题目来源:PIPIOJ 1360 删除最外层括号
【问题描述】
有效的括号字符串有 () , (A) , A+B, 其中A,B也为有效的括号字符串。若有效的括号字符串S非空,且不存在将S分解为A+B的方法(A,B皆为有效的括号字符串),那么S为不可分解的。给出字符串S,我们将其分解为 S = S1+S2+…+Sn, 其中每一个Si都是不可分解的。
现在要求你将S拆分为n个不可分解的串,并去除掉每一个不可分解串最外层的括号。
【输入输出】
1.输入:
输入包含多组测试样例。
每一组测试样例都是一个合法字符串S (|S|<100)。
2.输出:
对于每组样例,输出分解之后然后去除掉括号的字符串。
【样例】
样例输入:
(()())(())
()(())
样例输出:
()()()
()
【算法思路】
基本上有关于括号匹配的问题都会应用到栈。我们可以定义一个空字符串ans用于保存最后的结果。首先遍历整个有效的括号字符串,当遇到左括号时,判断栈里面是否已经存在左括号了,如果存在,那就说明这个左括号不是最外层的,假如到答案ans中,并且入栈。如果遇到右括号,先做出栈操作,假如栈中还有元素,那么此右括号就不是最外层的,加入到答案ans中,最后返回ans。
【算法描述】
#include <iostream>
#include <string>
using namespace std;
//定义栈结构体
#define sizeMax 100
typedef struct Stack
{
char data[sizeMax];
int top = -1;
}Stack;
string solve (Stack &s, string exp)
{
string ans;
for (int i=0; i < exp.size(); ++i)
{
//如果当前遍历到左括号
if (exp[i] == '(')
{
if (s.top != -1) //栈里面已经有左括号了,那么这个左括号就不能被分解了,加入答案
ans += exp[i];
s.data[++s.top] = i; //将左括号下标入栈
}
else
{
s.top--; //遇到右括号先出栈
if (s.top != -1)
ans += exp[i]; //只要栈中还有元素,那么就不是最外层括号,将其加入答案
}
}
return ans;
}
int main()
{
string exp;
while (cin >> exp)
{
Stack s;
cout << solve(s,exp) << endl;
}
return 0;
}