后缀表达式求值——栈的应用案例

105 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情

1、三种表达式

前缀表达式:<操作符><操作符><运算符> 中缀表达式:<操作符><运算符><操作符> 就是我们平常用的表达。如: 1+2*(8-5)-4/2 后缀表达式:<运算符><操作符><操作符>

因为在中缀表达式中有运算符优先级的问题,有时还会用括号改变运算顺序,所以就用的就比较少,我们可以先把中缀表达式转化为后缀表达式,在编译系统之后缀表达式也是更常见的。 如:1+2*(8-5)-4/2 的后缀表达式为:1285-*+42/-,后缀表达式的运算是这样的:

(1):从左到右<操作符>依次入栈,直到遇见<运算符>;

如:1、2、8、5依次入栈以后,下一个是减法运算符‘-’停止入栈

(2):出栈两个<操作符>分别给b,a、c=a<运算符>b,c入栈//注意a,b的复制顺序和相对于操作符的位置

如:b=5,a=8,c=8-5=3;c入栈

(4):循环(1)(2)步骤;

b=3,a=2,c=2*3=6;

b=1,a=6,c=1+6=7;

4、2入栈

b=2,a=4,c=4/2=2;

b=2,a=7,c=7-2=5;

2、代码解析

首先要写一个数据域为"double data;"的栈。

int IsNum(char c)//判断是否为数字字符,是就返回,不是就返回0
{
	if (c >= '0'&&c <= '9') return 1else return 0;
}
DataType postfix_exp(char *A)
{
	PSeqStack S;
	DataType Result, a, b, c;
	char ch;
	ch = *A++;
	S = Init_SeStack();//初始化
	while (ch!='#')//循环一二步骤知道字符串结束
	{
                //步骤一
		if (IsNum(ch)) {
			Push_SeqStack(S, ch - '0');
		}
                //步骤二
		else
		{
			Pop_SeqStack(S,&b);//a,b的赋值顺序是先给b赋值再给a赋值.
			Pop_SeqStack(S, &a);
			switch (ch)
			{
			case '+':c = a + b; break;//在运算时a在操作符的左边,b在操作符的右边
			case '-':c = a - b; break;
			case '*':c = a * b; break;
			case '/':c = a / b; break;
			case '%':c = (int)a % (int)b; break;
			}
			Push_SeqStack(S,c);
		}
		ch = *(A++);//下一个字符
	}
	GetTop_SeqStack(S,&Result);//运算结果出栈
	Destroy_SeqStack(&S);
	return Result;//返回运算结果
}

3、测试

void test02()
{
	char A[] = "1285-*+42/-#";
	printf("%f", postfix_exp(A));
}
int main()
{
	test02();
}

image.png