表达式求值

思路:

1.准备双栈,一个压入数字,另一个压入运算符。
2.判断运算符优先级进行运算。(技巧:运算符栈按优先级形成单调递增)

即当一个运算符入栈时,与栈顶元素比较。
1)如果栈顶运算符优先级高,那么计算栈顶运算符所对应的式子,此时就完成了运算符优先级高的先运算。
2)如果栈顶运算符优先级低,将当前运算符入栈。

注意:运算规则是从左到右(后面会具体看解释)。

实现代码:

#include<iostream>
#include<map>
#include<stack>
using namespace std;

stack<int> is;
stack<char> cs;

void operation() //计算运算符栈顶所对应的式子
{
	int x = is.top(); is.pop(); //运算符右值
	int y = is.top(); is.pop(); //运算符左值
	int c = cs.top(); cs.pop(); //运算符
	int s;
	if (c == '+') s = y + x;
	if (c == '-') s = y - x;
	if (c == '*') s = y * x;
	if (c == '/') s = y / x;
	is.push(s); //将得数压栈
}

int main()
{
	map<char, int> m{ {'+',1},{'-',1},{'*',2},{'/',2} }; // 运算符优先级
	string c;
	cin >> c;
	for (int i = 0; i < c.size(); i++)
	{
		int j = i,x = 0; 
		if (isdigit(c[i])) 
		{
			while (j<c.size() && isdigit(c[j])) x = x * 10 + c[j++] - '0'; // 超过各位的数字
			is.push(x); // 数字入栈
			i = j - 1; // 更新i值
		}
		else if (c[i] == '(') cs.push(c[i]); // '('直接入栈
		else if (c[i] == ')')
		{
			while (cs.top() != '(') operation(); // 将()中的元素全部计算完
			cs.pop();
		}
		else //判断运算符
		{
			while (cs.size() && m[cs.top()] >= m[c[i]]) //栈顶运算符与当前运算符优先级比较
				operation(); // /栈顶运算符比当前运算符优先级高时
			cs.push(c[i]); // 将当前运算符入栈
		}
	}
	while (!cs.empty()) operation(); // 剩余运算
	cout << is.top() << endl;
}

这里重点解释下判断运算符:

while (cs.size() && m[cs.top()] >= m[c[i]]) //等号为了运算能从左往右进行,同一优先级先按左边计算

想一想这里可不可以是if
这里用while是为了保证运算是从左往右执行的。
例:
3 - 2 * 7 + 2

while:

第一次:( + 入栈时 )

数字栈 : 7 2 3
运算符栈: * -

第二次:

数字栈:14 3
运算符符:-

循环结束

结果:-11 + 2 = -9

if:

数字栈 : 7 2 3
运算符栈: * -

数字栈:2 14 3
运算符栈:+ -
结果:先计算栈顶元素
14 + 2 = 16
3 - 16 = -13

以上可以看出whileif的区别,一个是左运算,一个是右运算。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值