Expression 数学表达式求值

问题描述

题目描述
给你一个数学表达式,请你求出它的值。
表达式中可能含有以下运算符:”+”、”-“、”“、”/“、”%”(取余)、”^”(指数)、”(“、”)”,其中优先级为: 括号 > “^” > “” = “/“ = “%” > “+” = “-“。

求解思路:

利用栈结构,将带括号的中缀表达式转为无括号的后缀表达式,再利用栈结构,对后缀表达式进行求值

中缀表达式转后缀表达式:
1、遇到数字时,不入栈,直接加入后缀表达式;
2、运算符:
(1)若为 ‘(‘,入栈;
(2)若为 ‘)’,则依次把栈中的的运算符出栈并加入后缀表达式中,直到出现’(‘,从栈中删除’(‘ ,但不加入后缀表达式;
(3)若为除括号外的其他运算符, 当其优先级高于除’(‘以外的栈顶运算符时,直接入栈。否则从栈顶开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符并加入加入后缀表达式,直到一个比它优先级低的或者遇到了一个左括号为止。比较完成后,将当前运算符入栈
3、当扫描的中缀表达式结束时,栈中的的所有运算符出栈加入后缀表达式。

后缀表达式计算规则:
从左向右扫描,遇到数字压栈,遇到操作符,弹出栈顶的两个元素,先弹出的元素在右边,后弹出来的在左边,进行计算后,将结果压栈,再往后扫描,直到扫描结束,输出栈顶元素,即为最终结果。

实现

#include <iostream>
#include <string>
#include <stack>
#include <cmath>

using namespace std;

int fun(char c)
{
	switch (c)
	{
		case '+':
			return 1;
		case '-':
			return 1;
		case '*':
			return 2;
		case '/':
			return 2;
		case '%':
			return 2;
		case '^':
			return 3;
		default:
			return -1;
	}
}

int main()
{
	string prefixExp;
	string suffixExp;
	getline(cin, prefixExp, '$');
	stack<char> midStack;
	stack<int> backStack;

	int len = prefixExp.length();
	for (int i = 0; i < len; i++)
	{
		if (prefixExp[i] == ' ')
		{
			continue;
		}
		if (prefixExp[i] >= '0' && prefixExp[i] <= '9')
		{
			suffixExp += prefixExp[i];
		}
		else
		{
			if (prefixExp[i] == '(')
			{
				midStack.push(prefixExp[i]);
			}
			else if (prefixExp[i] == ')')
			{
				while (midStack.size() != 0 && midStack.top() != '(')
				{
					char top = midStack.top();
					midStack.pop();
					suffixExp += top;
				}
				if (midStack.top() == '(')
				{
					midStack.pop();
				}
			}
			else
			{
				if (midStack.size() == 0)
				{
					midStack.push(prefixExp[i]);
				}
				else
				{
					char top = midStack.top();
					if (top != '(' && fun(prefixExp[i]) > fun(top))
					{
						midStack.push(prefixExp[i]);
					}
					else
					{
						while (midStack.size() > 0 && fun(top) >= fun(prefixExp[i]) && top != '(')
						{
							top = midStack.top();
							midStack.pop();
							suffixExp += top;
							if (midStack.size() > 0)
							{
								top = midStack.top();
							}
						}
						midStack.push(prefixExp[i]);
					}
				}
			}
		}
	}
	int stackLen = midStack.size();
	for (int i = 0; i < stackLen; i++)
	{
		char top = midStack.top();
		midStack.pop();
		suffixExp += top;
	}
	for (int i = 0; i < suffixExp.length(); i++)
	{
		if (suffixExp[i] >= '0' && suffixExp[i] <= '9')
		{
			backStack.push(suffixExp[i] - '0');
		}
		else
		{
			int top1 = 0;
			int top2 = 0;
			int top;
			if (backStack.size() > 0)
			{
				top1 = backStack.top();
				backStack.pop();
			}
			if (backStack.size() > 0)
			{
				top2 = backStack.top();
				backStack.pop();
			}
			switch (suffixExp[i])
			{
				case '+':
					top = top2 + top1;
					break;
				case '-':
					top = top2 - top1;
					break;
				case '*':
					top = top2 * top1;
					break;
				case '/':
					top = top2 / top1;
					break;
				case '%':
					top = top2 % top1;
					break;
				case '^':
					top = pow(top2, top1);
					break;
				default:
					return -1;
			}
			backStack.push(top);
		}
	}
	cout << backStack.top();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值