声明

关于栈和队列我已经在上两篇日志里面讲过了,但是在实际应用中,往往都是混用的,而且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;
}