表示式求值

2021-07-27 10:18:21 字數 1871 閱讀 2165

所謂表示式求值,就是寫乙個微型計算器。例如輸入:(1+9)* 2 / 2 - 1,輸出9。對於這樣的問題,我們一般利用棧,模擬數**算來完成。為了簡化問題,在繼續下面的分析之前,先在此作個約定:本文只討論+-*/()基本的四則運算,另外不對意外出現的符號(例如^)和不符合規範的數學表示式(例如2*-1)做異常處理。

我們用乙個字元陣列(即char s[1000])來儲存數學表示式,定義乙個全域性變數g_pos表示s[ ]的下標,下標從0開始。首先我們定義兩個棧,optr和opnd,分別儲存運算子和運算數,遇到運算數直接放進opnd;遇到運算子,分四種情況:

(1)遇到負號;

(2)遇到右括號;

(3)遇到左括號;

(4)遇到+-*/;

前三種情況容易理解,這裡就談下第四種情況。我們都知道四則運算是遵循先乘除再加減的(例如2*3+1),因此對於每個運算子,我們都要和optr的棧頂符號等級比較,如果這個符號的等級比optr棧頂符號等級高,什麼也不做,直接放進棧;如果小於等於,就需要把opnd的棧頂兩個數字抽出來,進行計算。這裡有個問題,在遇到第乙個運算子時,此時optr為空,而我們又需要與optr棧頂運算子比較等級,這時候怎麼辦?為了解決這個問題,我們在初始化optr的時候,放進乙個#,設定其等級為最低。

看到這裡你可能還存有乙個疑問,如何判定符號-時負號還是減號?例如-1+2 和 5-1+2。

分析發現,出現負號只有兩種情況:

(1)左邊是左括號,例如(-1+5*3);

(2)字串的第乙個字元,例如-5*6-1。

為了方便**書寫,若出現負號,就在運算數棧加入乙個數字0(這也就是下面**裡出現bool值is_minus的原因),即轉化一下表示式,例如-1+2轉化為0-1+2。

/**

* * author 劉毅(limer)

* date 2017-02-24

* mode c++

*/#include

#include

#include

#include

#include

using

namespace

std;

char s[1000];

int g_pos;//字元陣列的下標

/* 字元轉數字 */

double translation(int & pos)

if (s[pos] == '.')

}return integer + remainder;

}/* 返回運算子級別 */

int getlevel(char ch);}

/* 對兩個數進行運算 */

double operate(double a1, char op, double a2);}

/* 利用兩個棧進行模擬計算 */

double compute()

//2. 是右括號 )

else

if (s[g_pos] == ')')

optr.pop(); //刪除'('

}//3. 數字

else

if (s[g_pos] >= '0' && s[g_pos] <= '9')

//4. ( 左括號

else

if (s[g_pos] == '(')

//5. + - * / 四種

else

optr.push(s[g_pos]);

g_pos++;}}

while (optr.top() != '#')

return opnd.top();

}int main()

**我的個人部落格:

表示式求值

程式的說明見清華大學出版社 資料結構 c語言版 include include define stack init size 40 define stackincrement 20 define ok 1 define false 0 typedef structs stack typedef st...

表示式求值

既然是表示式求值,自然需要在記憶體中儲存計算結果以及中間值。在 用c語言寫直譯器 一 中提過 變數要求是若型別,而 c 語言中的 view plaincopy to clipboardprint?in basic io.h define memery size 26 typedef enum var...

表示式求值

寫了乙個下午,各種糾結,各種問,終於搞明白了。但是自己還是想出來的一點東西的。很爽歪歪的,哈哈。先貼第一次的 include include include include include includeusing namespace std char data 7 7 int sign char ...