表達式求值(TYVJ1043)

我他喵的被這題氣死好吧。(2年前的我調了3個小時,2年後調了1.5個小時)

求一箇中綴表達式的值(小學生都會好吧)

首先:計算機最喜歡的一定是後綴表達式,我們只要從頭到尾遍歷,然後碰到數字就壓入棧,碰到運算符就直接取出棧頂的2個元素直接進行計算,並將結果壓入棧。

那我們這裏要做的操作就是將中綴轉成後綴。

怎麼做呢?

1.碰到數字將他輸出

2.碰到左括號將他入棧。

3.碰到運算符只要棧頂符號的優先級不低於新符號,就不斷取出棧頂並輸出,最後把新符號入棧。

4.若是碰到右括號,就一直輸出直到碰到左括號。

#include <bits/stdc++.h>

using namespace std;
string s;
stack<char> sa;
stack<int> sb;//是int型的 
int cp(char x1,char x2)//判斷x1是否>=x2 
{
	if(x1=='^') return 1;
	if((x1=='*'||x1=='/')&&(x2!='^')) return 1;
	if((x1=='+'||x1=='-')&&(x2!='^'&&x2!='*'&&x2!='/')) return 1;
	return 0;
}
//優化:賦值然後直接比較 
int pow(int a,int x)
{
	int ans=1;
	while(x)
	{
		if(x&1) ans=ans*a;
		a=a*a;
		x>>=1;
	}
	return ans;
}
void cal(char ch)
{
	int x=sb.top();sb.pop();int y=sb.top();sb.pop();
	if(ch=='+') sb.push(x+y);
	if(ch=='-') sb.push(y-x);
	if(ch=='*') sb.push(x*y);
	if(ch=='/') sb.push(y/x);
	if(ch=='^') sb.push(pow(y,x));
	//x,y不要搞反了啊 
}
int main()
{ 
	cin>>s;int num=0;
	if(s[0]=='-') s='0'+s;
	for(int i=1;i<s.size();i++)
	{
		if(s[i]=='-'&&s[i-1]=='(') s=s.substr(0,i)+'0'+s.substr(i);
	}
	//對於負數的處理 
	for(int i=0;i<s.size();i++)
	{
	//	cout<<s[i]<<".";	
		if(s[i]>='0'&&s[i]<='9')
		{
			num=0;
			while(s[i]>='0'&&s[i]<='9'&&i<s.size())
			{
				num=num*10+(s[i]-'0');i++;		
			}
		//	printf("%d ",num);
			sb.push(num);
			i--;
			// 
		}
		else
		{	
			if(s[i]=='(') sa.push(s[i]);
			else if(s[i]==')') 
			{
				char x=sa.top();
				while(x!='(')
				{
					sa.pop();
				//	cout<<x<<" ";
					cal(x);
					x=sa.top();
				}
				sa.pop();
			}
			else
			{
			//	if(sa.size()) 放這裏有p用啊,放while裏面 
				{
					while(sa.size()&&cp(sa.top(),s[i]))//優先級大的先輸出 
					{
					//	cout<<sa.top()<<" "; 
						cal(sa.top());
						sa.pop();
					}
					//sa.push(s[i]);
				}
				sa.push(s[i]);
			}
		}
	}
	while(!sa.empty()) {/*cout<<sa.top()<<" ";*/if(sa.top()!='('&&sa.top()!=')') cal(sa.top());sa.pop();} 
	//會有多餘括號 
	cout<<sb.top()<<endl;
//	cout<<(2^4)<<endl;
	return 0;
} 
/*
2+(3*4-1)*2
*/ 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章