Skip to content

Latest commit

 

History

History
90 lines (70 loc) · 2.1 KB

栈.md

File metadata and controls

90 lines (70 loc) · 2.1 KB

#表达式求值

背景是从键盘录入一个带加减乘除括号的表达式,求出他的值。

首先有以下结论:

  • 乘除优先级高于加减。
  • 带括号的算式优先级高于不带括号的。

整个表达式可以看做栈模拟与后缀表达式,即对于一个算式:a+b,我们可以先让加号两边的数字入栈,再处理中间的运算符,这就是后缀表达式,记作a b +;一旦遇见括号,先让左括号入栈,遇到右括号时表示带括号的算式已经到头,可以计算,计算完毕之后将新结果入栈,完成更新。

递归以上操作直到表达式录入完毕。

一道经典的表达式求值题目(双栈、比较运算符优先级)--极简代码求解_diadestiny的博客-CSDN博客

# include<bits/stdc++.h>
# include<unordered_map>
using namespace std;
typedef long long ll;
stack<int>num;
stack<char>op;

void val()
{
	int x;
	int b=num.top();num.pop();
	int a=num.top();num.pop();
	
	if(op.top()=='+')
		x=a+b;
		else if(op.top()=='-')
		x=a-b;
		else if(op.top()=='*')
		x=a*b;
		else if(op.top()=='/')
		x=a/b;
	
	op.pop();
	
	num.push(x);
	
	
}
int main (void)
{
	string str;
	cin>>str;
	unordered_map<char,int>pr{{'+',1},{'-',1},{'*',2},{'/',2}};   //散列表,赋给不同运算符优先级
	
	for(int i=0;i<str.size();i++)
	{
		auto c=str[i];
		if(isdigit(c))           //如果表达式中这一项是数字,计算数值并入栈
		{
			int x=0;int j=i;
			while(j<str.size()&&isdigit(str[j]))
			x=x*10+str[j++]-'0';
			
			i=j-1;
			num.push(x);
		}
		else if(c=='(')         //左括号不用理会,直接存入
		op.push(c);
		else if(c==')')         //右括号则计算好所有到左括号之前的数值
		{
			while(op.top()!='(')
			{
				val();
			}
			op.pop();
		}
			else              //如果是四则运算符,入栈并计算已有数值
		{
			while(op.size()&&op.top()!='('&&pr[op.top()]>=pr[c])
			val();
			op.push(c);
			
		}
	}
	while(op.size())        //清理干净op中剩余的运算符
	val();
	
	cout<<num.top()<<endl;
		
	return 0;	
}