括号匹配(终极版)(典型栈的运用的题目,值得一看)

括号匹配时运用栈的一个典型例子,它是充分利用了栈先进后出的特性,在这之前,我们先来看一个简单的题目

括号匹配1

Description

输入一串带括号的表达式,判断输入的表达式是否合理。即判断括号是否匹配。为了简化题目,只输入左、右括号。如果表达式合理,输出YES,如果不合理,输出NO.

Format

Input

一行只包含左右括号的字符串。

Output

如果表达式合理,输出YES,如果不合理,输出NO.

Samples

Sample Input 1
()(())
Sample Output 1
YES
Sample Input 2
())(
Sample Output 2
NO

 如果你是初学栈,那是不是感觉毫无头绪,完全不知道这和栈有神马关系,没事,我们来慢慢理

有人会直接想直接比较左括号和右括号的数量就可以了,这是明显的错误,我们举个反例:)(

所以这个题的解题思路应该是当出现一个右括号的时候,就用当前最后一个左括号来匹配。如果出现右括号的时候前面没有未匹配的左括号。那么表示输出表达式不合理。

会了吗?我们来把上述的思路转化为专业术语:

首先,建立一个栈,用来存储左括号,而后定义一个临时输入的变量,边输入边判断,遇到违反上述规定的,就直接输出NO,然后return 0,直接结束。

但是这里得注意一个点,就是可能会在匹配结束后还有左括号没有使用,这是后也是不行的,所以要在匹配结束后检查一下栈是不是还有值。

ACcode

#include<bits/stdc++.h>
using namespace std;

stack<char> q1,q2;
int main(){
	char cmp;
	while (cin>>cmp){
		if (cmp=='('){
			q1.push(cmp);
		}else{
			if (q1.empty()==0){
				q1.pop();
			}else{
				cout<<"NO";
				return 0;
			}
		}
	}
	if (q1.empty()==0){
		cout<<"NO";
	}else cout<<"YES";
	return 0;
}

会了吗?会了的话括号匹配(终极版)你还是做不来

咳咳,所以说我们还要练,再来看看括号匹配2

括号匹配2

题目描述

假设一个表达式由三种括号和四种表达符号组成,现为了简化题目,只输入表达式中的括号。判断括号是否合理。注意:成对的括号内不能有未匹配的括号。暂时不考虑小括号一定要在大括号里面的问题

输入格式

只有三种括号的表达式

输出格式

如果可以匹配输出YES“,如果不可以匹配输出“NO”。

样例 #1

样例输入 #1
([)]{}
样例输出 #1
NO

这道题比括号匹配多了两个条件,那么就特判一下就可以了

因为在成对的括号内不能有未匹配的括号,所以只需用一个栈,然后判断栈顶的括号和输入的括号是不是匹配的就完了

#include<bits/stdc++.h>
using namespace std;

stack<int> q;
int main(){
    char cmp;
    while (cin>>cmp){
        if(cmp=='('||cmp=='['||cmp=='{')q.push(cmp);
        else{
//这个地方必须判断栈是不是空栈,否则会RE
            if (q.empty()==0&&(cmp==q.top()+1||cmp==q.top()+2)){//基于ASCLL码来写,不懂得可以查一下小括号,中括号和大括号的左右括号的关系
            	q.pop();
			}else {
				cout<<"NO";
				return 0;
			}
		}        
	}
	if (q.empty()==0){
		cout<<"NO";
	}else {
		cout<<"YES";
	}
	return 0;
}

现在会了吗,会了的话,我们就可以尝试一下括号匹配终极版了,题是不是还没发出来

题目描述

输入的括号表达式中含有三种括号:(),[],{},判断表达式是否合理。

注意,括号由里到外的顺序只能是小括号,中括号,大括号。但是相同括号可以重叠,比如[[]]是可以的。

输入格式

一个括号表达式

输出格式

输出YES或者NO

样例 #1

样例输入 #1

[{[]}]

样例输出 #1

NO

样例 #2

样例输入 #2

{[]}

样例输出 #2

YES

 这个题比之前还要多了一个条件,就是括号从里到外的顺序只能是小括号,中括号,大括号。这就需要加一个判断等级的变量,因为我们知道,小括号的ASCLL码是小于中括号的。中括号的是小于大括号的,所以就可以基于此来写一个判断等级的变量,只不过需要在每一次输入左括号和匹配成功的时候更新一下就可以了

#include<bits/stdc++.h>
using namespace std;

stack<int> q;
char cnt;//判断等级的变量
int main(){
    char cmp;
    while (cin>>cmp){
        if(cmp=='('||cmp=='['||cmp=='{'){
        	q.push(cmp);
        	cnt=cmp;//更新
		}
        else{
            if (q.empty()==0&&(cmp==q.top()+1||cmp==q.top()+2)&&cnt<=cmp){
            	cnt=cmp;//更新
            	q.pop();
			}else {
				cout<<"NO";
				return 0;
			}
		}        
	}
	if (q.empty()==0){
		cout<<"NO";
	}else {
		cout<<"YES";
	}
	return 0;
}

看了这么久,作者也写了这么久,能不能点一个赞,在收藏一下呢?最好的话在点个关注吧

谢谢啦!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值