#696~698+1598.括号匹配问题

本蒟蒻的第五篇题解,望大家多多见谅!

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!!!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值