C++表達式求值(利用數據結構棧)


唉,剛剛用C++又又一次寫了一個較完好的表達式求值程序,最后精簡后程序還不到100行。這不經讓我

想到了大一上學期剛學c語言時自己費了好大的勁,寫了幾百行並且功能還不是非常齊全(當時還不能計算有括號的表

達式)的簡單計算器程序。剛把兩個程序對照了一下。感觸還是挺深的,同一時候也再一次體現了數據結構在程序設計

中的重要性。

曾經的那個程序有漏洞並且邏輯復雜,所以就不提了,僅僅說說如今改進后的程序,其思想主要是用到了

棧先進后出的數據結構。在該程序中建有兩個棧:一個用於存儲運算符,還有一個用於存儲操作數或運算結果。基本

過程是:

(1):首先設置操作數棧為空棧,設置運算符棧以‘#’為棧底元素(其優先級最低)。

(2):通過為棧內棧外運算符設置值而比較其優先級

(3):依次去找到表達式中的全部運算符和操作數,對於操作數直接入棧。運算符則和運算符棧的

棧頂運算進行比較優先級,若棧內優先級大,則進行對應操作並操作數和棧內運算符都出棧,若優先級相等僅僅需

棧內運算符出棧繼續查找下一個運算符就可以,若棧內優先級低則棧外運算符入棧。依次循環知道分析完表達式中

的全部運算符和操作數就可以。

(4):最后在操作數棧中將僅僅會剩下唯一的一個元素,而該元素也將就會是所求表達式的值。

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

/*推斷符號間的優先關系函數
*1表示>,0表示=,-1表示<
*c1棧內的算符。c2棧外的算符
*/
int Judge(char c1,char c2)
{
	int a1,a2;
	if('+'==c1||'-'==c1) a1 = 3;
	if('*'==c1||'/'==c1)a1 = 5;
	if('('==c1) a1 = 1;
	if(')'==c1) a1 = 7;
	if('#'==c1) a1 = 0;

	if('+'==c2||'-'==c2)a2 = 2;
	if('*'==c2||'/'==c2)a2 = 4;
	if('('==c2) a2 = 6;
	if(')'==c2) a2 = 1;
	if('#'==c2) a2 = 0;
	if(a1>a2) return 1;
	if(a1==a2) return 0;
	if(a1<a2) return -1;
}
//符號運算函數
double run(char c ,double d1,double d2)
{
	switch (c)
	{
	case '+':
		return d1+d2;
		break;
	case '-':
		return d1-d2;
		break;
	case'*' :
		return d1*d2;
		break;
	case '/':
		return d1/d2;
		break;
	default:
		return 0.0;
		break;
	}
}
int main()
{
	char * op = "+-*/()#";
	string str ;
	cin>>str;
	//給表達式字符串str加入'#'結束標識符
	str.append(1,'#');
	stack<char> OPTR;//運算符棧
	stack<double> OPND;//操作數棧
	int a = -1;
	//先將#符號入棧
	OPTR.push('#');
	while(true)
	{
	 int b = a+1;
	 a = str.find_first_of(op,a+1);
	 if(a==string::npos) break;
	 if(a!=b)
	 {
	 string ss(str,b,a-b);
	 double d=atof(ss.c_str());
	 //數據先入棧
	 OPND.push(d);
	 }
	 //運算符優先級比較
	 int ju = Judge(OPTR.top(),str[a]);
	 if(-1==ju)//棧外優先級大直接入棧
	 {
	     OPTR.push(str[a]);
	 }
	 if(0==ju)//棧內外優先級相等則出棧
	 {
		 OPTR.pop();
	 }
	 if(1==ju)//棧內優先級大,出棧進行運算
	 {
		 double d1 = OPND.top();
		 OPND.pop();
		 double d2 = OPND.top();
		 OPND.pop();
		 d1 = run(OPTR.top(),d2,d1);
		 //運算結果入棧
		 OPND.push(d1);
		 OPTR.pop();
		 a--;
	 }
	}
	//刪除表達式最后的'#'結束標識符
	str.erase(str.length()-1,1);
	cout<<str<<" = "<<OPND.top()<<endl;
}



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM