括号匹配加强版
描述 Description
对于一个由(,),[,]括号组成的字符串,求出其中最长的括号匹配字串。 具体来说,满足如下条件的字符串成为括号匹配的字符串: (1) (),[] 是括号匹配的字符串。 (2) 若A是括号匹配的串,则(A)或[A] 是括号匹配的字符串。 (3) 若A和B都是括号匹配的字符串,则A+B也是括号匹配的字符串。(这里的+是字符串的加法运算)。 例如:(),[],([]),()() 都是括号匹配的字符串,而][,[( ]),(]则不是。 字符串A的子串是指由A中连续若干个字符组成的字符串。例如:A,B,C,ABC,CAB,ABCCABC都是ABCABC的子串。空串是任何字符串的子串。
输入格式 Input Format
输入一行,为一个仅由()[]组成的非空字符串。(括号都是英文输入法的括号)
输出格式 Output Format
输出也仅有一行,为最长的括号匹配子串。若有相同长度的子串,输出位置靠前的子串。
样例输入 Sample Input
【输入样例1】 ([(][()]]()
【输入样例2】 ())[]
样例输出 Sample Output
【输出样例2】 [()]
【输出样例2】 ()
时间限制 Time Limitation 1s
注释 Hint 【数据规模】 对于20%的数据,字符串长度<=100 对于50%的数据,字符串长度<=10,000 对于100%的数据,字符串长度<=1,000,000
思路:这道题栈的经典应用,需要注意的就是如果不匹配栈需要清空。对于题上给的 A匹配,B匹配,则A+B匹配 我们可以把每个匹配的bool标记,这样最后枚举的时候 for i=1.....n bool[i]=1 肯定是连续的。
代码:
#include<cstring> #include<cstdio> #include<algorithm> #include<iostream> using namespace std; int stack[1000100]; int top=0; //char ans[1000100]; char c[1000100]; bool f[1000100]; int n=0; //int len=0; //int id=0; //int t=0; inline void push(int x) { stack[++top]=x; } void check(int i) { //cout<<stack[top]<<‘ ‘; if(top>0) { if(c[stack[top]]==‘(‘) { if(c[i]==‘]‘) top=0; else if(c[i]==‘(‘||c[i]==‘[‘) push(i); else if(c[i]==‘)‘) { f[stack[top]]=1; f[i]=1; --top; } } else if(c[stack[top]]==‘[‘) { if(c[i]==‘)‘) top=0; else if(c[i]==‘(‘||c[i]==‘[‘) push(i); else if(c[i]==‘]‘) { f[i]=1; f[stack[top]]=1; --top; } } else if((c[stack[top]]==‘)‘)||(c[stack[top]]==‘]‘)) { top=0; push(i); } } else { //cout<<"ccccc:"<<i<<‘ ‘; if((c[i]!=‘]‘)||(c[i]!=‘)‘)) { push(i); } else return; } //cout<<stack[top]<<‘ ‘; } void work() { int id; int len=0; int ans=0; //for(int i=1;i<=n;i++) cout<<f[i]<<‘ ‘;cout<<endl; for(int i=1;i<=n;++i) { //cout<<f[i]<<‘ ‘; if(f[i]) { ++len; int t=i+1; while(f[t]) { ++len; ++t; } i=t-1; if(len>ans) { ans=len; id=i-len+1; } len=0; } } //cout<<"id:"<<id<<endl; //cout<<"ans:"<<ans<<endl; for(int i=id;i<=id+ans-1;++i) { printf("%c",c[i]); } } int main() { //freopen("a.txt","r",stdin); //freopen("b.txt","w",stdout); memset(f,0,sizeof(f)); char ch; ch=getchar(); while(ch>=20) { c[++n]=ch; //cout<<c[n]<<‘ ‘; ch=getchar(); } //cout<<endl; //cout<<"n:"<<n<<endl; for(int i=1;i<=n;++i) { check(i); } //cout<<endl; work(); return 0; }