后缀表达式求值

中缀表达式转换为后缀表达式

首先说明一点,中缀表达式中间是可以有括号的,而括号的作用在于扰乱计算的顺序,使得括号内的计算优先级高于括号外的,但是在括号内,四则运算的法则依然是成立的。
而后缀表达式则严格按照计算符出现的顺序来执行操作。
在下面的代码中,用到了栈,解释一下使用栈的理由。

无论是加减乘除,都需要两个操作数,但是我们阅读中缀表达式的时候都是从左向右看,当你发现一个运算符的时候,你只能确定你的左边一定有一个已经计算完毕的操作数,但是你不能保证你的下一个字符也是操作数,因为可能存在优先级比你高的操作数在后面等待计算,你使用的只是返回值,所以我们使用栈来进行缓冲。

由于栈是后进先出的,所以当优先级低的操作符出现时,高级的操作符必须已经完成计算(后缀表达式严格按照计算符出现的顺序),所以我们要从栈顶开始把优先级高的操作数全部出栈,然后将低优先级的运算符入栈。(如果不这么做,当扫描输入完成时,栈由上往下出栈进入后缀表达式时,低优先级运算符会在高优先级运算符的左边)

对于括号的处理,括号的优先级是最高的,把他当成优先级最高的运算符处理即可,但是要注意把左括号也出栈。

代码中对后缀表达式中加入了空格,是为了方便对于后缀表达式的计算,想一想如果后缀表达式有一堆数字,1234,你如何区分他是12 和34还是1 和234,我们加入分隔符来进行分辨,这里的分隔符是空格

#include<iostream>
#include<map>
#include<cstring>
#include<cctype>
using namespace std;
map<char, int>ID;
int top = 0;
int head = -1;
const int maxn = 200;
char postfix[maxn];
char infix[maxn];
char S[maxn];
int main(void)
{
	int len = 0;
	char ch;
	while ((ch = getchar()) != '\n')
	{
		infix[len++] = ch;
	}
	ID['+'] = ID['-'] = 1;
	ID['*'] = ID['/'] = 2;
	for (int i = 0; i < len; i++)
	{
		if (infix[i] == ' ')
		{
			continue;
		}
		else if (infix[i] == '(')
		{
			S[++top] = infix[i];
		}
		else if (isdigit(infix[i]))
		{
			while (1)
			{
				postfix[++head] = infix[i];
				if (isdigit(infix[i + 1]))
				{
					i++;
				}
				else
				{
					break;
				}
			}
			postfix[++head] = ' ';
		}
		else if (infix[i] == ')')
		{
			while (S[top] != '(')
			{
				postfix[++head] = S[top--];
				postfix[++head] = ' ';
			}
			top--;
		}
		else
		{
			while (top>0&&ID[S[top]] >= ID[infix[i]])
			{
				postfix[++head] = S[top--];
				postfix[++head] = ' ';
			}
			S[++top] = infix[i];
		}
		for (int i = 1; i <= top; i++)
		{
			printf("S[%d] = %c\n", i, S[i]);
		}
	}
	while (top>0)
	{
		postfix[++head] = S[top--];
		postfix[++head] = ' ';
	}
	printf("%s", postfix);
	return 0;
}

后缀表达式求值

得到了后缀表达式,进行计算求值就是一件很简单的事情,因为不用考虑优先级的问题,只要从左往右扫描,如果是数字就放进栈里,如果是运算符,就从栈中提取两个数,把计算结果放回即可。

int calculate()
{
	int h = 0,x=0;
	int s[maxn];
	int len = strlen(postfix);
	for (int i = 0; i < len; i++)
	{
		switch (postfix[i])
		{
		     case '+':s[--h] += s[h + 1]; break;
		     case '-':s[--h] -= s[h + 1]; break;
		     case '*':s[--h] *= s[h + 1]; break;
		     case '/':s[--h] /= s[h + 1]; break;
			 case ' ':break;
		     default:
		    {
				 x = 0;
				 while(1)
				 {
					 if (isdigit(postfix[i]))
					 {
						 x = x * 10 + (postfix[i] - '0');
						 i++;
					 }
					 else
					 {
						 break;
					 }
				 }
		    }
			s[++h] = x;
			for (int i = 0; i <= h; i++)
			{
				printf("%d ", s[i]);
			}
			printf("\n");
			break;
		}
	}
	return s[1];
}

完整代码

#include<iostream>
#include<map>
#include<cstring>
#include<cctype>
using namespace std;
map<char, int>ID;
int top = 0;
int head = -1;
const int maxn = 200;
char postfix[maxn];
char infix[maxn];
char S[maxn];
int calculate()
{
	int h = 0,x=0;
	int s[maxn];
	int len = strlen(postfix);
	for (int i = 0; i < len; i++)
	{
		switch (postfix[i])
		{
		     case '+':s[--h] += s[h + 1]; break;
		     case '-':s[--h] -= s[h + 1]; break;
		     case '*':s[--h] *= s[h + 1]; break;
		     case '/':s[--h] /= s[h + 1]; break;
			 case ' ':break;
		     default:
		    {
				 x = 0;
				 while(1)
				 {
					 if (isdigit(postfix[i]))
					 {
						 x = x * 10 + (postfix[i] - '0');
						 i++;
					 }
					 else
					 {
						 break;
					 }
				 }
		    }
			s[++h] = x;
			for (int i = 0; i <= h; i++)
			{
				printf("%d ", s[i]);
			}
			printf("\n");
			break;
		}
	}
	return s[1];
}
int main(void)
{
	int len = 0;
	char ch;
	while ((ch = getchar()) != '\n')
	{
		infix[len++] = ch;
	}
	ID['+'] = ID['-'] = 1;
	ID['*'] = ID['/'] = 2;
	for (int i = 0; i < len; i++)
	{
		if (infix[i] == ' ')
		{
			continue;
		}
		else if (infix[i] == '(')
		{
			S[++top] = infix[i];
		}
		else if (isdigit(infix[i]))
		{
			while (1)
			{
				postfix[++head] = infix[i];
				if (isdigit(infix[i + 1]))
				{
					i++;
				}
				else
				{
					break;
				}
			}
			postfix[++head] = ' ';
		}
		else if (infix[i] == ')')
		{
			while (S[top] != '(')
			{
				postfix[++head] = S[top--];
				postfix[++head] = ' ';
			}
			top--;
		}
		else
		{
			while (top>0&&ID[S[top]] >= ID[infix[i]])
			{
				postfix[++head] = S[top--];
				postfix[++head] = ' ';
			}
			S[++top] = infix[i];
		}
	}
	while (top>0)
	{
		postfix[++head] = S[top--];
		postfix[++head] = ' ';
	}
	printf("%s\n", postfix);
	int ans = calculate();
	printf("%d", ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我还是忘不了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值