中缀表达式转换成后缀表达式+计算,自己写的。

单单数据结构上,不考虑具体实现来说,这个算法是这样的:

从左到右扫描每一个字符。

1.遇到数字直接输出。

2.遇到'(',直接压栈。

3.遇到')',弹出栈元素直到遇到左括号(左括号也弹出)。

4.扫描到其他运算符:

          (1)当前字符优先级>栈顶字符优先级,直接入栈。

          (2)当前字符优先级<=栈顶字符优先级,栈一直pop到栈底或者遇到左括号(左括号不弹出),然后当前字符入栈。

5.扫描到头栈内仍有元素,栈操作依次吐到空即可。

 

另,操作符优先级(数越小优先级越高)

团长  2    ^     

营长  3    * / %   

排长  4    + - 

(   ) 不参与运算符优先级比较,如上述方法特殊处理。为了程序正常运行,可以把左括号设成最低优先级。

 

自己测试了几个用例,都通过了。

语言是C++。

 

它用到的数据结构是:一个存放运算符的栈,名字是Sop,和一个存放后缀表达式的vector,名字是res。

 

它的C++具体规则是:

先设置好每个运算符的优先级。

从左到右依次遍历每一个字符。

1.遇到数字,直接放到push_back到res(也就是存放最终结果的vector)里面。

2.遇到 '(',直接压到Sop(算法用到的栈)里面。

3.遇到 ')',就把Sop的栈顶元素依次push_back到res里面,直到遇到左括号(左括号也弹出),同时注意,不要把左括号和右括号输出到res里。

4.遇到其他的运算符,

          (1)如果Sop是空的,直接入栈。

          (2)比较Sop的栈顶运算符和当前运算符的优先级:

                            如果当前运算符str[i]的运算符   优先于   栈顶运算符Sop.top(),那么str[i]入栈。
                            如果不是,就一直弹出栈顶的运算符到vector里面,直到弹到栈空或者弹到左括号(左括号不弹出),然后压入当前运算符。

5.当for遍历完所有的字符之后,Sop这个栈里还有运算符,那么依次弹出栈顶元素直到栈空。

 

这个小demo是操作数只能个位的操作数。

然后是计算函数,后缀表达式的计算很简单,就不详细说了。

贴一下代码。2020.4.19,更新了代码。

#include <bits/stdc++.h>
using namespace std;
 
bool isNum(char a){
	return (a<='9'&&a>='0');
}
char* NifixToSuffix(string str){
	string res;
	stack<char> Sop;
	int k=0;
	map<char,int> priority;
	priority['(']=1;
	priority['^']=2;
	priority['/']=priority['*']=priority['%']=3;
	priority['+']=priority['-']=4;
	priority[')']=5; 
	
	for(int i=0;i<str.size();i++){
	
		if(isNum(str[i])) res.push_back(str.c_str()[i]);	
		else if(str[i]=='(') Sop.push(str.c_str()[i]);
		else if(str[i]==')')
		{
			while(Sop.top()!='('){
				res.push_back(Sop.top());
				Sop.pop();
			}
			//remove '(' operator
			Sop.pop();
		}	
		else//是运算符 
		{	
			if(Sop.empty()) Sop.push(str.c_str()[i]);
		    else if(priority[str[i]]<priority[Sop.top()])
				Sop.push(str.c_str()[i]);
			else{
				while(priority[str[i]]>=priority[Sop.top()])
				{
					if(Sop.top()=='(') break;
					res.push_back(Sop.top());
					Sop.pop();
					if(Sop.empty()) break;
				}	
				Sop.push(str.c_str()[i]);	
			}
		}
			
	}
	
	while(!Sop.empty()){
		res.push_back(Sop.top());
		Sop.pop();
	}
	cout<<"size of the res is "<<res.size()<<endl;	
}
 
int getValue(string  expr) 
{
	int res=0;
	stack<int> S;
	while(!S.empty())  S.pop();
	
	for(int i=0;i<expr.size();i++)
	{
//		cout<<"now is: "<<expr[i]<<endl;
		if(isNum(expr[i]))	S.push(expr[i]-'0');
		else{
			int a=S.top();S.pop();
			int b=S.top();S.pop();
			
			cout<<"now: "<<i<<"  "<<expr[i]<<b<<endl;

			if(expr[i]=='+') S.push(a+b);
			else if(expr[i]=='-') S.push(b-a);
			else if(expr[i]=='*') S.push(a*b);
			else if(expr[i]=='/') S.push(b/a);
			else if(expr[i]=='%') S.push(b%a);
			else if(expr[i]=='^') S.push(int(pow(b,a)));
		}
	}
	return S.top();
}
int main() {
	string expression("4/2+(2*3-3*4)");
	
//	string res="42/23*34*-+" ;
	string res=NifixToSuffix(expression);
	cout<<getValue(res)<<endl;
	
	
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值