表达式求值(中缀表达式转为后缀表达式)--数据结构与算法--栈

本文介绍了表达式求值中的算符优先法,重点讲解了如何使用栈实现后缀表达式求值算法,以及中缀表达式到后缀表达式的转换过程。通过实例和代码展示了如何在C语言中实现这些功能。

@表达式求值

前言

表达式求值是程序设计语言编译中的一个最基本问题,其实现是栈应用的又一个典型例子。“算符优先法”,是一种简单直观、广为使用的表达式求值算法。
要把一个表达式翻译成正确求值的一个机器指令序列,或者直接对表达式求值,首先要能够正确解释表达式。算符优先法就是根据算术四则运算规则确定的运算优先关系,实现对表达式的编译或解释执行的。
在表达式计算中先出现的运算符不一定先运算,具体运算顺序是需要通过运算符优先关系的比较,确定合适的运算时机,而运算时机的确定是可以借助栈来完成的。将扫描到的不能进行运算的运算数和运算符先分别压入运算数栈和运算符栈中,在条件满足时再分别从栈中弹出进行运算。

案例分析

表达式分析

任何一个表达式都是由**操作数(operand)、运算符(operator)和界限符(delimiter)**组成的,统称它们为单词。
一般地,操作数既可以是常数,也可以是被说明为变量或常量的标识符;运算符由运算对象上来说由单目,双目和三目运算符;基本界限符有左右括号和表达式结束符等。
为了叙述的简洁,在此仅讨论简单算术表达式的求值问题,这种表达式只含加、减、乘、除4种双目运算符,并且操作数只有一位。
读者不难将它推广到更一般的表达式上。
下面把运算符和界限符统称为算符。

在表达式求值时,表达式一般有三种表达方式:

后缀表达:<操作数><操作数><运算符>
中缀表达:<操作数><运算符><操作数>
后缀表达:<运算符><操作数><操作数>
日常生活我们用的都是中缀表达式:1+2*(8-5)-4/2。

后缀表达式解释

由于中级表示中有算符的优先级问题,有时还采用括号改变运算顺序,因此一般在 表达式求值中,较少采用中缀表示,在编译系统中更常见的是采用后缀表示。
1+2*(8-5)-4/2的计算顺序和用后缀表示的计算顺序如图所示。
表达式计算顺序

1)后缀表达式(也称逆波兰式)求值 由于后缀表达式的操作数总在运算符之前,并且表达式中即无括号又无优先级的约 束,算法比较简单。

具体做法是,只使用一个操作数栈,当从左向右扫描表达式时,每遇 到一个操作数就送人栈中保存,每遇到一个运算符就从栈中取出两个操作数进行当前的 计算,然后把结果再人栈,直到整个表达式结束,这时送人栈顶的值就是结果。 下面是后缀表达式求值的算法,在下面的算法中假设,每个表达式是合乎语法的,并且假设后缀表达式已被存人一个足够大的字符数组A中,且以#为结束字符。

表达式求值算法实现(后缀表达式)

编译环境

头文件在博主博客中:
https://blog.youkuaiyun.com/Liu1_1_/article/details/133855448

/*表达式求值*/
#include<stdio.h>
#include"Seqstack.h"

算法代码

typedef char DataType;  //更改栈元素

//判断字符是否为操作数 
int IsNum(char c)
{
   
   
	/*判断字符是否为操作数  若是返回1 否则返回0*/
	if (c >= '0' && c <= '9')
		return 1;
	else
		return 0;
}


double postfix_exp(char* A)
{
   
   
	/*本函数返回由后缀表达式A表达的表达式运算结果*/
	PSeqStack S;
	double Result, a, b, c;
	char ch;
	ch = *A++;
	S = Init_SeqStack(); 			/*初始化栈*/
	while (ch != '#')
	{
   
   
		if (IsNum(ch))   Push_SeqStack(S, ch - '0');
		else
		{
   
   
			Pop_SeqStack(S
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值