四则运算(后缀表达式的应用)

一、引入

在程序中实现四则运算,我们不仅需要考虑加减乘除的顺序,还需要考虑括号的问题,这使得我们的程序非常麻烦,但基于这种数据结构,我们可以很方便的进行操作。

例如:中缀表达式 9+(3-1)*3+10/2,我们可以把它化为后缀表达式(也叫逆波兰表达式) 9 3 1 - 3 * + 10 2 / + 对于这样一串表达式,我们可以用栈来对它进行操作。

二、运用

基本思想是:

对于每一个元素,如果是数字,则入栈,如果是符号,则将栈顶的两个元素取出进行运算,再将运算结果入栈。

运算过程:

1、先将 9 3 1 入栈,下一个元素是减号,则将3 和1 取出,进行3 - 1 = 2 ,再将2入栈
2、将3 入栈后,下一个元素是乘号,则进行2 * 3 = 6 ,再将6入栈
3、进行9 + 6 = 15 然后入栈,10 、2 入栈后进行10 / 2 = 5 入栈,再进行15 + 5 = 20
最终得出答案等于20;

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

从左到右依次遍历中缀表达式,如果是数字则输出,如果是符号,则判断当前符号与此时栈顶的符号的优先级,若当前符号优先级高于栈顶,则入栈,否则将栈内符号全部出栈,将当前符号入栈;

过程
接下来引用《大话数据结构》里的图片:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<cmath>
#include<stack>
using namespace std;
typedef long long ll;
stack <char> st1;
stack <int> st2;
int fun(char c)		//判断符号的优先级
{
	if (c == '+' || c == '-')
		return 1;
	else if (c == '*' || c == '/')
		return 2;
	else
		return 3;
}
void js(char c)		//将栈顶两个数拿出来计算,并将结果压入栈中
{
	int b = st2.top();
	st2.pop();
	int a = st2.top();
	st2.pop();
	int tmp = 0;
	if (c == '+')
		tmp = a + b;
	else if (c == '-')
		tmp = a - b;
	else if (c == '*')
		tmp = a * b;
	else
		tmp = a / b;
	st2.push(tmp);
}
int main()
{
	string a;
	getline(cin, a);		//以字符串的形式输入
	int l = a.length();
	for (int i = 0; i < l; i++)
	{
		if (a[i] >= '0' && a[i] <= '9')
		{
			int tmp = 0;
			while (a[i] >= '0' && a[i] <= '9')
			{
				tmp = tmp * 10 + a[i] - '0';
				if (a[i + 1] >= '0' && a[i + 1] <= '9')
					i++;
				else break;
			}
			st2.push(tmp);	//可以读入多位数字
		}
		else
		{
			if (st1.empty())
				st1.push(a[i]);
			else
			{
				if (fun(a[i]) >= fun(st1.top())||fun(st1.top())==3)
				{
					st1.push(a[i]);
					if (a[i] == ')')		//	遇到括号则将左括号之前的符号全部输出进行运算
					{
						st1.pop();
						while (st1.top() != '(')
						{
							js(st1.top());
							st1.pop();
						}
						st1.pop();
					}
				}
				else
				{
					while (!st1.empty())		//如果当前符号优先级比栈顶的优先级小,则将栈中所有符号进行运算并将当前符号压入栈中
					{
						js(st1.top());
						st1.pop();
					}
					st1.push(a[i]);
				}
			}
		}
	}
	while (!st1.empty())		//	将剩余符号进行运算
	{
		js(st1.top());
		st1.pop();
	}
	cout << st2.top();
	return 0;
}
//9+(3-1)*3+10/2
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

橘落京城

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

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

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

打赏作者

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

抵扣说明:

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

余额充值