使用栈判断括号是否匹配

什么是栈?

栈有好几个意思,比如遵循先进后出规则的线性表(与“队列”相反);程序运行时系统分配变量地址空间的地方,遵循先进后出的原则(与“堆”相反);在CPU寄存器的一块存储介质,访问时遵循先进后出的原则

我们今天所说的栈,是第一个意思

什么是先进后出

先进后出,就是先进去的后出来。就这么简单。

比如我有数据x, y, z。我先把x放入栈,再把y放入栈,再把z放入栈。我想取出时,先取出z,再取出y,再取出x

这就是一个简单的示意图 

入栈

入栈指数据存入

出栈

出栈指数据取出

C++给我们的栈

// 导入头文件
#include <stack>

// 栈在std命名空间里
using namespace std;

// 定义一个栈,栈里的每个元素是int类型的
stack<int> st;

// 将1入栈
st.push(1);

// 将2入栈
st.push(2);

// 返回栈顶
int tmp = st.top();

// 出栈,没有返回值
st.pop();

// 如果栈为空
if(st.empty());

什么是括号    :-)

括号分为小括号“()”,中括号“[]”,和大括号“{}”,其中每个括号分为左括号“([{”和右括号“}])”。每个左括号的后面都要有相同的右括号对应,而且括号不能错位。即可以([{}])而不能([{]})

什么是判断括号是否匹配

判断括号匹配就是判断括号的使用是否合理。具体怎么使用见《什么是括号》  :-)

怎么用栈判断括号是否匹配呢?

思路

用栈判断的思路是这样的:

1.遍历字符串

2.如果发现括号

1)判断是否为左括号

如果为左括号,则入栈

否则(为右括号),则出栈,并将取出结果与遍历到的括号比较,如果不是同一个类型的括号,直接返回-1 (表示错误)

3.遍历完毕,未发现错误,返回正确0 (表示正确)

代码实现

为(yin)了(wei)方(wo)便(bi)起(jiao)见(lan),这段代码写在了一个源文件里。实际开发中,应该要将类型的定义、函数的声明、头文件的包含等放在一个.h文件里,将功能函数放在一个.c的文件里,main函数放在main.c文件里。大家千万别学我这样只放在一个文件里哦

#include <stdio.h>
#include <stack>
#include <string.h>

// 定义括号类型的枚举 
typedef enum{
	LITTLE, // 小括号
	MIDDLE, // 中括号
	LARGE,  // 大括号
	ERROR   // 错误 
}brackets_t; 

// 获取括号类型
brackets_t get_brackets_type(char c){
	brackets_t result;
	switch(c){
		case '(':
		case ')':
			result = LITTLE;
			break;
		case '[':
		case ']':
			result = MIDDLE;
			break;
		case '{':
		case '}':
			result = LARGE;
			break;
		default:
			result = ERROR;
			break;
	}
	return result;
}

// 判断括号是否是左括号,是返回1
int is_left(char c){
	if(c == '(' || c == '[' || c == '{')return 1;
	return 0;
} 

// 出栈 如果栈为空返回-1,否则返回栈顶元素 
// 这句话定义了一个泛型(类型占位符),在编译过程中会将占位符改为具体类型
// 这个占位符就是T 
template<class T> 
T pop(std::stack<T> *st){
	// 判断栈是否为空
	if(!(*st).empty()){ // 不为空则正常调用 
		T result = (*st).top();
		(*st).pop();
		return result;
	}
	// 为空则返回T类型的-1 
	// 采用更厉害的强制转换 
	T *tmp; // 创建一个临时(T *)类型变量 
	int itmp = -1; // 创建一个临时int型变量 
	tmp = (T *)&itmp; // 让tmp存itmp的地址,需要进行强制转换
	return *tmp; // 使用T的访问规则读取itmp的地址 
}

// 判断括号组合是否正确,正确返回0 
int is_brackets_right(const char *str){
	std::stack<brackets_t> st; // 建立栈
	// 遍历 字符串
	int len = strlen(str);
	for(int i = 0; i < len; i++){
		// 存储当前括号的类型
		brackets_t br = get_brackets_type(str[i]);
		// 如果是括号 进行括号判断 
		if(br != ERROR){
			// 如果当前括号是左括号
			if(is_left(str[i]))
				// 那么获取括号类型并存入栈
				st.push(br);
			//否则出栈并与当前括号比较类型 
			else {
				// 出栈 
				brackets_t sr = pop<brackets_t>(&st);
				// 如果类型不相等 返回-1 
				if(sr != br)return -1;
			}
		}
	}
	// 循环结束,如果没有问题,返回0
	return 0; 
}

int main(void){
	char str[16];
	scanf("%s", str);
	int if_it = is_brackets_right(str);
	if(if_it == 0)printf("It is right\n");
	else printf("It is not right\n");
	return 0;
}

这就是栈的初级用法——判断括号是否匹配

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值