声明
关于栈和队列我已经在上两篇日志里面讲过了,但是在实际应用中,往往都是混用的,而且OJ上P1148这道题还超级麻烦,所以……
看题:
题目描述:
对于一个由(,),[,]括号组成的字符串,求出其中最长的括号匹配字串。 具体来说,满足如下条件的字符串成为括号匹配的字符串: (1) (),[] 是括号匹配的字符串。 (2) 若A是括号匹配的串,则(A)或[A] 是括号匹配的字符串。 (3) 若A和B都是括号匹配的字符串,则A+B也是括号匹配的字符串。(这里的+是字符串的加法运算)。 例如:(),[],([]),()() 都是括号匹配的字符串,而][,[( ]),(]则不是。 字符串A的子串是指由A中连续若干个字符组成的字符串。例如:A,B,C,ABC,CAB,ABCCABC都是ABCABC的子串。空串是任何字符串的子串。
输入:
输入一行,为一个仅由()[]组成的非空字符串。(括号都是英文输入法的括号)
输出:
输出也仅有一行,为最长的括号匹配子串。若有相同长度的子串,输出位置靠前的子串。
题解:
拿到这道题,然后我们的思路就是建立一个类似于栈的队列,输入一个后和队列中上一个元素比较,如果出现 [ )
或者 ( ]
的时候,是不合法的,直接让队尾end为零,如果合法的比如一直是( ( [ [ [
什么的,或者是 ( ) [ ]
这种情况,那么是可以存进去的,如果匹配,那么就end-=2;然后将所有合法的 first 坐标和 last 坐标存进一个结构体数组里面,然后合并,合并完了之后不要想着什么直接输出,题目上说,如果出现 ([][][])[()]()
这类情况也是可以的,所以我们就再次开一个循环,然后如果当前存储的last+1等于下一个的first,那么他们两个合在一起也是合法的,于是就合并啊,合并啊。
写了一百行的小弱鸡,大神六七十行搞定!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<string> #include<cstring> #include<queue> #include<iomanip> using namespace std; struct note { int first; int last; }; bool mycmp(note x,note y) { return x.first<y.first; } bool yourcmp(note x,note y) { return (x.last-x.first)>(y.last-y.first); } note Fans[1000001],Lans[1000001],Cans[1000001]; int list[1000001],ans=1,num=0; int main() { ios::sync_with_stdio(false); string s1,s2,s3; cin>>s1; long long top=0,end=0; list[0]=0; for(int i=1;i<s1.size();i++) { list[++end]=i; if(s1[list[end]]==')'&&end==0) { end=-1; continue; } if(s1[list[end]]==']'&&end==0) { end=-1; continue; } if(end==0) continue; if(s1[list[end]]==')'&&s1[list[end-1]]=='[') { end=-1; continue; } if(s1[list[end]]==']'&&s1[list[end-1]]=='(') { end=-1; continue; } if(s1[list[end]]==')'&&s1[list[end-1]]=='(') { Fans[top].first=list[end-1]; Fans[top].last=list[end]; end-=2; top++; continue; } if(s1[list[end]]==']'&&s1[list[end-1]]=='[') { Fans[top].first=list[end-1]; Fans[top].last=list[end]; end-=2; top++; continue; } } sort(Fans,Fans+top,mycmp); Lans[1].first=Fans[1].first; Lans[1].last=Fans[1].last; for(int i=0;i<top;i++) { if(Fans[i].last>Lans[ans].last) { Lans[++ans].first=Fans[i].first; Lans[ans].last=Fans[i].last; } } for(int i=1;i<=ans;i++) { if(Lans[i].last+1==Lans[i+1].first) { Lans[i+1].first=Lans[i].first; continue; } else { Cans[++num].first=Lans[i].first; Cans[num].last=Lans[i].last; } } sort(Cans+1,Cans+num+1,yourcmp); for(int i=Cans[1].first;i<=Cans[1].last;i++) cout<<s1[i]; return 0; }
|