408-数据结构-栈应用-括号匹配&表达式求值

括号匹配

代码中的括号通常符合一下特性:

  1. 括号成对存在
  2. 左右括号通常类型匹配,大括号匹配大括号

如果存在括号序列(((()))())。从左向右,后进入的左括号先被匹配,体现了LIFO原则,所以可以使用栈来实现。

算法过程:
访问括号序列,如果访问到左括号,只需要进行压入栈中即可。而如果碰到右括号则需要进行判断:

  1. 查看当前栈是否为空,如果为空,说明没有左括号与这个括号匹配,匹配失败,否则继续。
  2. 弹出栈顶,如果类型符合,则匹配成功,查看下一个括号。
  3. 如果类型不符合说明序列有误,匹配失败

重复访问,直到访问完毕所有括号序列,此时再进行查看栈,如果栈不为空,说明有左括号没有匹配到右括号,序列有误。

代码实现:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define MaxSize 10
bool bracketMatch(char * str, int length){
	//数组实现栈
	char Stack[MaxSize];
	int top = -1;

	for (int i = 0 ; i < length ;i ++){
		//左括号入栈
		if (str[i] == '(' || str[i] == '{' || str[i] =='[')
			Stack[++top] = str[i];
		else if (str[i] == ')' || str[i] == '}' || str[i] ==']'){
		//检测到右括号,弹出栈顶进行匹配
			if (top == -1)
				return false;
			char top_char = Stack[top--];
			switch (top_char){
				case '{':
					if (str[i] != '}')
						return false;
					break;
				case '(':
					if (str[i] != ')')
						return false;
					break;
				case '[':
					if (str[i] != ']')
						return false;
			}

		}else 
			return false;			//含有非括号成分,序列有误
	}
	return top == -1;				//最后查看栈顶,左括号是否完全匹配
}


表达式求值

表达式说明

主要解决的为这类算数表达式:(1+2) * 3 / 4。
表达式通常有三类东西:运算符±,操作数,界符即括号
表达式通常分为三类:

  1. 前缀表达式,也称为波兰表达式。用处不大。
  2. 中缀表达式,也就是用的最经常的表达式
  3. 后缀表达式,也称为逆波兰表达式。常用于计算机。最经常考,考点

前缀中缀后缀指的是运算符在运算值之间的位置,加减乘除都是二目运算符,通常写在两个运算值中间,所以这种称为中缀表达式,其他两种类似。

前缀表达式,后缀表达式的优点:可以不需要界符

表达式转换算法

将中缀表达式转换为前缀后缀表达式遵循两步走:

  1. 确定各个运算符的运算顺序
  2. 根据运算顺序按照前缀或者后缀的规则进行写

由于运算符的运算顺序有同级别的存在,所以运算顺序不一定相同,那么转换出来的前缀后缀表达式不一定相同。

如果需要转换出来的表达式相同,需要规定死运算顺序。

  • 一般转换成后缀表达式采用“左优先”原则,即运算符如果优先级相同,从左往右优先,如果优先级不同,优先级高的先算。
  • 转换为前缀表达式采用“右优先”

这样导致结果还有一种好处,转换为后缀表达式中的操作符从左往右的顺序与定义运算顺序相同,前缀表达式从右往左的顺序与定义运算顺序相同。

将后缀表达式转换为中缀表达式:
从左往右扫描

  1. 如果为操作数,入栈
  2. 如果为操作符,取出栈顶两个操作数,先取出来的为右操作数,后取出来的为左操作数
  3. 按照中缀编写,添加括号,压入栈中
  4. 继续迭代,直至扫描完毕

如果是表达式求值,将计算结果压入栈中即可。

中缀表达式转换为后缀表达式算法与求值

重点内容

算法过程:按照顺序扫描序列,碰到不同类型进行不同操作:

  1. 如果为操作数,将操作数压入操作数栈中
  2. 如果为操作符,弹出操作符栈顶所有优先级大于或者等于该操作符的操作符,弹出的时候进行相应转化,压回操作数栈。然后将操作符压入操作符栈中。
  3. 如果为界符,左界符直接压入操作符栈中,如果为右界符,弹出操作符栈直至到左界符(一并弹出),并且进行相应计算,界符不加入后缀表达式
  4. 直至扫描完毕,将操作符栈所有操作符弹出进行相应计算,最后剩余在操作数栈的即为结果

如果需要计算值,压回操作数栈压入计算的值即可,最终剩余的就是表达式的结果。

栈的其他应用以及队列应用

栈的其他应用:递归调用,用于保存现场数据
队列的应用:

  1. 树的层次遍历
  2. BFS
  3. 操作系统中的FCFS
  4. 以及缓冲区的队列
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值