給出一個表達式,求取表達式的值

給出一個表達式,求取表達式的值

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <stack>
using namespace std;
/***
思路:
1.字符串預處理,針對可能出現的“{,},[,],-”等特殊情況進行替換,判斷‘-’是負號還是減號,負號前面+0,轉變成減法運算
2.將中綴字符串轉變爲後綴字符串數組
3.對後綴字符串數組進行求解
***/
int main(int argc, char const *argv[])
{
	string str;
	while(getline(cin,str))
		calcExp(str);
	return 0;
}
void calcExp(string &str){
	preProcess(str);
	vector<string>vstr=mid2post(str);
	double res=calcPostExp(vstr);
	cout<<res<<endl;
}
/***
對字符串進行預處理:
1.將‘{、}、[,]’替換成'()'
2.將'-'前面添加0轉變成減法運算
***/
void preProcess(string &str){
	int num=str.size();
	for(int i=0;i<num;i++){
		if(str[i]=='{')
			str[i]='(';
		else if (str[i]=='}')
			str[i]=')';
		else if(str[i]=='[')
			str[i]='(';
		else if(str[i]==']')
			str[i]=')';
		else if(str[i]=='-'){
			if(i==0)
				str.insert(0,1,'0');
			else if(str[i-1]=='(')
				str.insert(i,1,'0');
		}

	}
}
//中綴轉後綴
vector<string>& mid2post(string &str){
	vector<string>vstr;
	satck<char>cstack;
	string temp="";
	//掃描字符串
	for(int i=0,n=str.size();i<n;i++){
		temp="";
		//若爲數字
		if(str[i]>='0'&&str[i]<='9'){
			temp+=str[i];
			while(i+1<n&&str[i+1]>='0'&&str[i+1]<='9'){
				temp+=str[i+1];
				i++;
			}
			vstr.push_back(temp);
		}
		//棧空或遇見字符'('
		else if(cstack.empty()||str[i]=='(')
			cstack.push(str[i]);
			//若棧頂優先級高
		else if(cmpPriority(cstack.top(),str[i])){
			//當前字符爲')',棧中元素出棧,入字符串數組中,直到遇到'('
			if(str[i]==')'){
				while(!cstack.empty()&&cstack.top()!='('){
					temp+=cstack.top();
					cstack.pop();
					vstr.push_back(temp);
					temp=""
				}
				cstack.pop();
			}
			//棧中優先級高的元素出棧,入字符串數組,直到優先級低於當前字符
			else{
				while(!cstack.empty()&&cmpPriority(cstack.top(),str[i])){
					temp+=cstack.top();
					cstack.pop();
					vstr.push_back(temp);
					temp="";
				}
				cstack.push(str[i]);
			}
		}
		//當前字符優先級高於棧頂元素,直接入棧
		else
			cstack.push(str[i]);	
	}
	//棧中還存在運算符時:出棧,存入字符串數組
	while(!cstack.empty){
		temp+=cstack.top();
		cstack.pop();
		vstr.push_back(temp);
		temp="";
	}
	return vstr;
}

//比較當前字符與棧頂字符的優先級,若棧頂高,返回true
bool cmpPriority(char top,char cur){
	if((top=='+'||top=='-')&&(cur=='+'||cur=='-'))
		return true;
	if((top=='*'||top=='/')&&(cur=='+' || cur=='-'|| cur=='*' || cur=='/'))
		return true;
	if(cur==')')
		return true;
	return false;
}
//對後綴表達式進行求值:主要是根據運算符取出兩個操作數進行運算
double calcPostExp(vector<string>&vstr){
	stack<double>opstack;
	int num,op1,op2;
	string temp="";
	stringstream ss;
	for(int i=0,n=vstr.size();i<n;i++){
		temp=vstr[i];
		//如果當前字符串是數字,利用字符串流轉化爲int型
		if(temp[0]>='0'&&temp[0]<='9'){
			ss<<temp;//通過流將數值轉爲字符串,或將字符串轉爲數值。
			ss>>num;
			opstack.push(num);
		}
		//若是操作符,取出兩個操作數,進行運算,並將結果存入
		else if(vstr[i]=='+'){
			op2=opstack.top();
			opstack.pop();
			op1=opstack.top();
			opstack.pop();
			opstack.push(op1+op2);
		}
		else if(vstr[i]=='-'){
			op2=opstack.top();
			opstack.pop();
			op1=opstack.top();
			opstack.pop();
			opstack.push(op1-op2);
		}
		else if(vstr[i]=='*'){
			op2=opstack.top();
			opstack.pop();
			op1=opstack.top();
			opstack.pop();
			opstack.push(op1*op2);
		}
		else if(vstr[i]=='/'){
			op2=opstack.top();
			opstack.pop();
			op1=opstack.top();
			opstack.pop();
			opstack.push(op1+op2);
		}
	}
	return opstack.top();
}

 

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