P1433. 字符串匹配问题

说明

字符串中只含有括号 (),[],<>,{},判断输入的字符串中括号是否匹配。如果括号有互相包含的形式,从内到外必须是<>,(),[],{},
例如。输入: [()] 输出:YES,而输入([]),([)]都应该输出 NO。

输入格式

文件的第一行为一个整数 n,表示以下有多少个由括好组成的字符串。
接下来的 n 行,每行都是一个由括号组成的长度不超过 255 的字符串。

输出格式

在输出文件中有 n 行,每行都是 YES 或 NO。

样例

输入数据 1

1
2
3
4
5
6
5
{}{}<><>()()[][]
{{}}{{}}<<>><<>>(())(())[[]][[]]
{{}}{{}}<<>><<>>(())(())[[]][[]]
{<>}{[]}<<<>><<>>>((<>))(())[[(<>)]][[]]
><}{{[]}<<<>><<>>>((<>))(())[[(<>)]][[]]

输出数据 1

1
2
3
4
5
YES
YES
YES
YES
NO
  • 思路跟多数栈的题目一样,基本遵循左括号入栈,右括号出栈的原则,左括号要在右括号之前入栈
  • <> , () , [] , {}的优先级依次增高 ,优先级高的在外,优先级低的在内。所以,当栈为空时直接入栈,当栈不为空时,要考虑优先级,让优先级栈顶元素低或者和栈顶元素相同的入栈。对< ( [ { 分开进行讨论
  • 当栈顶元素和遍历到的元素匹配时出栈
  • 当整个字符串遍历完成后,当栈中有元素时,证明右括号与左括号不匹配,顾表达式不合法
  • 当栈为空时,表达式合法
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
#include<iostream>
#include<stack>
using namespace std;//
stack <char> s;
int main(){
int n;
cin>>n;
for(int j=0;j<n;j++){
string a;
cin>>a;
for(int i=0;i<a.size();i++){
if(!s.empty()){//栈为空就需要压入一个,不为空就进行判断
if(s.top()=='<'){//当栈顶为<
if(!s.empty()&&a[i]=='>'){//与<匹配出栈
s.pop();
}
else if(a[i]=='<'){//优先级<= < 时入栈
s.push(a[i]);
}
else{//都不匹配时,退出if判断进行下一次循环,下一个字符判断
break;
}
}
else if(s.top()=='('){
if(a[i]=='<'||a[i]=='('){
s.push(a[i]);
}
else if(!s.empty()&&a[i]==')'){
s.pop();
}
else{
break;
}
}
else if(s.top()=='['){
if(a[i]=='<'||a[i]=='('||a[i]=='['){
s.push(a[i]);
}
else if(!s.empty()&&a[i]==']'){
s.pop();
}
else{
break;
}
}
else if(s.top()=='{'){
if(a[i]=='<'||a[i]=='('||a[i]=='['||a[i]=='{'){
s.push(a[i]);
}
else if(!s.empty()&&a[i]=='}'){
s.pop();
}
else{
break;
}
}
else{
break;
}
}
else{
s.push(a[i]);
}
}
if(!s.empty()){
cout<<"NO"<<endl;
}
else{
cout<<"YES"<<endl;
}
while(!s.empty()){
s.pop();
}
}
return 0;
}