本蒟蒻的第五篇题解,望大家多多见谅!
1.#696.表达式括号匹配(stack)
P
a
r
t
Part
Part
1
1
1 读题
题目描述:
假设一个表达式有英文字母(小写)、运算符
(
+
,—,
∗
,
/
)
(+,—,*,/)
(+,—,∗,/)和左右小(圆)括号构成,以“
@
@
@”作为表达式的结束符。
请编写一个程序检查表达式中的左右圆括号是否匹配,若匹配,则返回“
Y
E
S
YES
YES”;否则返回“
N
O
NO
NO”。表达式长度小于
255
255
255,左圆括号少于
20
20
20个。
输入格式:
输入文件stack.in包括一行数据,即表达式。
输出格式:
输出文件stack.out包括一行,即“
Y
E
S
YES
YES”或“
N
O
NO
NO”。
输入样例1:
2*(x+y)/(1-x)@
输出样例1:
YES
输入样例2:
(25+x)*(a*(a+b+b)@
输出样例2:
NO
P a r t Part Part 2 2 2 思路
我们要对左右括号值匹配,如果相同输出“ Y E S YES YES”,不同输出“ N O NO NO”。
P a r t Part Part 3 3 3 代码
方法一(简单法):
#include <bits/stdc++.h>
using namespace std;
char s[1000];
int main() {
int n=0,m=0;
cin.getline(s+1,1000);
int len=strlen(s+1);
for(int i=1;i<=len;i++){
if(s[i]=='(')
n++;
if(s[i]==')')
m++;
}
if(n==m){
cout<<"YES";
}
else
cout<<"NO";
return 0;
}
}
方法二(栈):
#include<bits/stdc++.h>
using namespace std;
int top;
int main(){
string a;
char s[1000];
cin>>a;
cin.getline(s+1,1000);
int len=strlen(s+1);
for(int i=0;i<len;i++){
if(a[i]=='(')s[++top]=1;
if(a[i]==')'){
if(s[top]==1&&top>0)
s[--top]=0;
else{
cout<<"NO";
break;
}
}
if(a[i]=='@'){
if(top==0)cout<<"YES";
else cout<<"NO";
}
}
return 0;
}
P a r t Part Part 4 4 4 总结
本题考查从左到右扫描括号序列,如果是左括号入栈,如果是右括号进行匹配。匹配成功继续,否则结束。
2.#697.括弧匹配检验(check)
P
a
r
t
Part
Part
1
1
1 读题
题目描述:
假设表达式中允许包含两种括号:圆括号和方括号,其嵌套的顺序随意,如
(
[
]
(
)
)
([]())
([]())或
[
(
[
]
[
]
)
]
[([][])]
[([][])]等为正确的匹配,
[
(
]
)
[(])
[(])或
(
[
]
(
)
([]()
([]()或
(
(
)
)
)
(()))
(()))均为错误的匹配。
现在的问题是,要求检验一个给定表达式中的括弧是否正确匹配?
输入一个只包含圆括号和方括号的字符串,判断字符串中的括号是否匹配,匹配就输出“
O
K
OK
OK” ,不匹配就输出“
W
r
o
n
g
Wrong
Wrong”。输入一个字符串:
[
(
[
]
[
]
)
]
[([][])]
[([][])],输出:
O
K
OK
OK。
输入格式:
输入仅一行字符(字符个数小于255)
输出格式:
匹配就输出 “
O
K
OK
OK” ,不匹配就输出“
W
r
o
n
g
Wrong
Wrong”。
输入样例1:
[(])
输出样例1:
Wrong
输入样例2:
[([][])]
输出样例2:
OK
P a r t Part Part 2 2 2 思路
我们要对左右括号匹配,如果相同输出“ O K OK OK”,不同输出“ W r o n g Wrong Wrong”。
P a r t Part Part 3 3 3 代码
代码(栈):
#include<bits/stdc++.h>
using namespace std;
int top;
bool f;
int main(){
string s;
char s[1000];
cin>>s;
cin.getline(s+1,1000);
int len=strlen(s+1);
int n,m;
for(int i=0;i<len;i++){
if(s[i]=='('||s[i]==')')n++;
if(s[i]=='['||s[i]==']')m++;
if(s[i]=='('||s[i]=='[')a[++top]=s[i];
if(s[i]==')'){
if(a[top]=='(')
top--;
else{
f=1;
break;
}
}
if(s[i]==']'){
if(a[top]=='[')
top--;
else{
f=1;
break;
}
}
}
if(n%2==1||m%2==1){
cout<<"Wrong";
return 0;
}
if(f==1)
cout<<"Wrong";
else
cout<<"OK";
return 0;
}
P a r t Part Part 4 4 4 总结
本题考查左括号入栈,遇到右括号时,看栈顶括号与右括号是否能配对。如果两个括号都是小括号或中括号,那么二者配对,左括号出栈。否则括号不匹配。如果遍历到右括号时,发现栈空,那么存在右括号无法匹配。如果遍历结束时,栈不为空,那么存在左括号无法匹配。
3.#698.字符串匹配问题(strs)
P
a
r
t
Part
Part
1
1
1 读题
题目描述:
字符串中只含有括号(),[],<>,{},判断输入的字符串中括号是否匹配。
如果括号有互相包含的形式,从内到外必须是<>,(),[],{},例如:
输入: [()] 输出:
Y
E
S
YES
YES,而输入([]),([)]都应该输出
N
O
NO
NO。
输入格式:
文件的第一行为一个整数
n
n
n,表示以下有多少个由括好组成的字符串。
接下来的
n
n
n行,每行都是一个由括号组成的长度不超过
255
255
255的字符串。
输出格式:
在输出文件中有
n
n
n行,每行都是
Y
E
S
YES
YES或
N
O
NO
NO。
输入样例:
5
{}{}<><>()()[][]
{{}}{{}}<<>><<>>(())(())[[]][[]]
{{}}{{}}<<>><<>>(())(())[[]][[]]
{<>}{[]}<<<>><<>>>((<>))(())[[(<>)]][[]]
><}{{[]}<<<>><<>>>((<>))(())[[(<>)]][[]]
输出样例:
YES
YES
YES
YES
NO
P a r t Part Part 2 2 2 思路
我们要运行 n n n组,对左右括号值匹配,如果相同输出“ Y E S YES YES”,不同输出“ N O NO NO”。
P a r t Part Part 3 3 3 代码
栈:
#include<bits/stdc++.h>
using namespace std;
char str[1000005],stk[1000005];
int main(){
int n,top=0;
scanf("%d",&n);
for(int k=1;k<=n;k++){
top=0;
scanf("%s",str);
int l=strlen(str);
for(int i=0;i<=l;i++){
if(str[i]=='('){
if(stk[top]==3){
printf("NO\n");
break;
}
else{
stk[++top]=1;
}
}
if(str[i]=='['){
if(stk[top]==1||stk[top]==3){
printf("NO\n");
break;
}
else {
stk[++top]=2;
}
}
if(str[i]=='<'){
stk[++top]=3;
}
if(str[i]=='{'){
if(stk[top]==1||stk[top]==2||stk[top]==3){
printf("NO\n");
break;
}
else{
stk[++top]=4;
}
}
if(str[i]==')'){
if(top>0){
if(stk[top]==1){
stk[top]==0;
top--;
}
}
else {
printf("NO\n");
break;
}
}
if(str[i]==']'){
if(top>0){
if(stk[top]==2){
stk[top]==0;
top--;
}
else{
printf("NO\n");
break;
}
}
}
if(str[i]=='>'){
if(top>0){
if(stk[top]==3){
stk[top]==0;
top--;
}
}
else {
printf("NO\n");
break;
}
}
if(str[i]=='}'){
if(top>0){
if(stk[top]==4){
stk[top]==0;
top--;
}
}
else {
printf("NO\n");
break;
}
}
if(str[i]==str[l]){
if(top==0){
printf("YES\n");
break;
}
else{
printf("NO\n");
break;
}
}
}
}
return 0;
}
P a r t Part Part 4 4 4 总结
本题考查:
如果遇到左括号
如果栈空,则入栈。
如果栈不空
如果当前左括号优先级小于等于栈顶左括号优先级,左括号入栈。
否则不匹配。
如果遇到右括号
如果栈空,则不匹配。
如果栈不空
看栈顶左括号能否与该右括号配对,如果配对则出栈
否则不匹配。
4.#1598. 括号匹配
P
a
r
t
Part
Part
1
1
1 读题
题目描述:
为了让幻想乡的妖怪们更富有智慧,贤者八云紫决定在幻想乡开设计算机基础、C语言程序设计、数据结构等课程。琪露诺听说课上可以玩电脑,于是兴冲冲地把大妖精拉上,报名参加了C语言基础课程。
琪露诺当然什么都听不懂(毕竟她的智商只有⑨),所以每次上课她都全程跟大妖精玩昆特牌,下课后请其他妖怪帮她写作业。⑨个月后她把雾之湖所有的妖怪和妖精都委托了一遍,现在她找不到别人,只能再次找你了。
这次的作业是这样的:给你一个括号序列,其中有圆括号()、方括号[]、花括号{}和尖括号<>,请问该序列是否合法。
合法的括号序列可以按如下方式递归定义:
(1)空序列是合法的;
(2)若A和B是合法的括号序列,则AB(将B连接到A的后方)也是合法的括号序列;
(3)若A是合法的括号序列,则在两端添加一对括号,( A )、[ A ]、{ A }、< A >
都是合法的括号序列。
输入格式:
第一行是一个正整数
T
T
T,表示数据组数;
之后
T
T
T行,每行包含一个字符串,表示待判断的括号序列。保证字符串非空且只会包含()[]{}<>这8种字符。
输出格式:
对于每组数据,若该序列是合法的则输出
Y
e
s
Yes
Yes,否则输出
N
o
No
No。
输入样例:
3
(([]))
([(]))
{<><>}<{{(}}>)
输出样例:
Yes
No
No
P a r t Part Part 2 2 2 思路
我们要对左右括号值匹配,如果相同输出“ Y E S YES YES”,不同输出“ N O NO NO”。
P a r t Part Part 3 3 3 代码
栈:
#include<bits/stdc++.h>
using namespace std;
char str[1000005],stk[1000005];
int main(){
int n,top=0;
scanf("%d",&n);
for(int k=1;k<=n;k++){
top=0;
scanf("%s",str);
int l=strlen(str);
for(int i=0;i<=l;i++){
if(str[i]=='('){
stk[++top]=1;
}
if(str[i]=='['){
stk[++top]=2;
}
if(str[i]=='<'){
stk[++top]=3;
}
if(str[i]=='{'){
stk[++top]=4;
}
if(str[i]==')'){
if(top>0){
if(stk[top]==1){
stk[top]==0;
top--;
}
}
else {
printf("No\n");
break;
}
}
if(str[i]==']'){
if(top>0){
if(stk[top]==2){
stk[top]==0;
top--;
}
else{
printf("No\n");
break;
}
}
}
if(str[i]=='>'){
if(top>0){
if(stk[top]==3){
stk[top]==0;
top--;
}
}
else {
printf("No\n");
break;
}
}
if(str[i]=='}'){
if(top>0){
if(stk[top]==4){
stk[top]==0;
top--;
}
}
else {
printf("No\n");
break;
}
}
if(str[i]==str[l]){
if(top==0){
printf("Yes\n");
break;
}
else{
printf("No\n");
break;
}
}
}
}
return 0;
}
P a r t Part Part 4 4 4 总结
本题考查:
如果遇到左括号
如果栈空,则入栈。
如果栈不空
如果当前左括号优先级小于等于栈顶左括号优先级,左括号入栈。
否则不匹配。
如果遇到右括号
如果栈空,则不匹配。
如果栈不空
看栈顶左括号能否与该右括号配对,如果配对则出栈
否则不匹配。
看完题解后,会不会感到很简单呢?赶快去试试吧!
5.总结
括号匹配并不难,只要多思考,就能AC!!!