最长有效括号串
题目描述:
给定一个只含左右小括号的括号串序列exp,找出其中最长的有效括号串。
Input:
输入一个只含左右小括号的括号字符串,以换行结束。
Output:
输出其中最长的有效括号串。输出的每个括号之后均有空格。
思路分析:
这道题一开始我以为是:
求出每个括号要最长长度,但不是这样。
正确理解应该是:
求出每个完整括号,拥有最多个并且是连续的,才是最长的。
这道题的可以先用
-
“begin”来记录输出括号的初始位置,
-
“maxbegin”记录输出括号的最大初始位置,
-
“end”是输出括号的长度。
-
并且用栈来标记括号的状态。
解题顺序:
- 先枚举字符串,当得到是右括号“(”的时候,将该下标压入栈中。
- 如果下一个下标依然是右括号,继续重复第一个操作。
- 如果下一个下标是左括号,这时候要做个判断,栈中是否为空。
- 如果为空,说明无右括号与左括号匹配了,并且初始位置也要改变了,“begin”将会变为该下标+1.
- 如果不为空的话,删除栈中的顶元素,在进行一个判断,栈中是否为空。
- 如果为空的话,说明这先前里面栈中只有一个右括号与其匹配,将“end”改变括号的长度,“maxbegin”被赋值成“begin”。
- 如果不为空的话,说明这先前面栈中不止一个右括号,这时候就需要改变“end”的括号长度,以及这时候“maxbegin”被赋值成顶元素下标加1(这里因为顶元素下标加1是右括号,他已经在这步操作被左括号匹配,而先前的右括号还未匹配,所以最大初始位置需要改动)。
代码:
#include<cstdio>
#include<stack>
#include<string>
#include<queue>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
using namespace std;
int main()
{
int begin=0,maxbegin,end=0;//初始位置,最大初始位置,与字符括号长度(包括了左右括号)
stack<int>q;//创建队列
string s;
cin >> s;//输入字符串
for(int i=0;i<s.length();i++)
{
if(s[i]=='(')//找到右括号
{
q.push(i);//将其下标压栈中
}
else
{//判断栈中是否为空
if(q.empty())//如果为空,说明连续已断,初始位置发生改变
{
begin=i+1;
}
else
{
q.pop();//删除栈中顶元素
//判断栈中是否为空
if(q.empty())//如果为空
{
if(end<i-begin+1)
{
end=i-begin+1;//改变括号长度
maxbegin=begin;//将初始位置赋给最大初始位置
}
}
else//如果不为空
{
if(end<i-q.top())
{
end=i-q.top();//改变括号长度
maxbegin=q.top()+1;//改变最大初始位置
}
}
}
}
}
for(int i=maxbegin;i-maxbegin<end;i++)//输出有效括号子串
{
printf("%c ",s[i]);
}
}