解析表示式 C 實現

2022-07-03 07:03:12 字數 3856 閱讀 9425

1. 中綴、字首、字尾表示式

對於乙個人可識別的表示式:1+(2+3)*4-5

根據操作符的位置不同分為:

①中綴表示式:1+(2+3)*4-5

②字首表示式:- + 1 * + 2 3 4 5  

③字尾表示式:1 2 3 + 4 * + 5 -

字首表示式和字尾表示式裡面已經包含了計算順序,因此不需要括號來確定優先順序

2. 中綴轉字首

2.1 中綴轉字首

①按運算子優先順序對所有的運算單位加括號

((1+((2+3)*4))-5)

②將運算子移動到對應括號的前面

- ( + ( 1 * ( + 2 3 ) 4 )) 5 )

③去掉括號,得到字首表示式

- + 1 * + 2 3 4 5

轉換的計算機實現:

(1)表示式樹

(2)棧 

①兩個棧,運算子棧s1、儲存中間結果棧s2

②從右到左掃瞄表示式

③遇到運算元,壓棧s2

④遇到運算子,比較其與s1棧頂運算子優先順序

若s1為空,或棧頂為右括號 ')' ,則此運算子入棧s1

若優先順序比棧頂運算子高或相等,則此運算子入棧s1

若比棧頂優先順序低,將s1棧頂運算子出棧壓到s2裡面,然後繼續與s1棧頂運算子比較。重複④

⑤遇到括號

右括號直接壓入s1

左括號,則依次彈出s1棧頂運算子到s2,直到遇到右括號,此時將這一對括號丟棄

⑥重複直到表示式最左邊

⑦將s1剩餘運算子依次彈出壓到s2

⑧依次彈出s2中元素,得到字首表示式  

1

string midextopreex(string &preex)2;

4 map priority = ,,,};

5ostringstream strstream;6//

string *res = new string();

7 stacks1,s2;

8int preex_len =preex.size();

9struct

node temp;

10for(int i=preex_len-1;i>=0;--i)

14else

if((preex[i]>='

0' && preex[i]<='

9') || preex[i] =='

.')

2021

//strtmp<22

for(int j=i-1;j>=0;j--)

28else

if(preex[j] == '

' || preex[j] == '\t'

) 31

else34}

35while(!num_tmp.empty())

39 temp.num =strtmp.str();

40 temp.flag = true;41

s2.push(temp);42}

43else

if(ops.find(preex[i]) != ops.end())

49else

if(priority[preex[i]] >=priority[s1.top().op])

54else

if(priority[preex[i]] 59 temp.flag = false

;60 temp.op =preex[i];

61s1.push(temp);62}

63}64else

if(preex[i] == ')'

) 69

else

if(preex[i] == '('

) 74 s1.pop();//

丟棄右括號

75//

此左括號不作處理,相當於丟棄了76}

77else80}

81while(!s1.empty())

85while(!s2.empty())

89else

92s2.pop();93}

94return

strstream.str();

95 }

2.2 字首表示式解析計算

①從右到左掃瞄表示式

②遇到數字,則數字壓棧,遇到運算子,取出棧頂的兩個數做運算:棧頂 op 次頂,結果入棧

③重複直到表示式最左側

1 template2 t cal(t n1,t n2,char

op)3

12return

res;13}

1415

int cal_prerc(string &preex)16;

19bool int_or_double = true; //

true代表表示式中只有int

20if(preex.find('

.') != string

::npos)

23 stackint_stack;

24 stackdouble_stack;

25for(int i = ex_size-1;i>=0;i--)

29if(preex[i]>='

0'&&preex[i]<='9'

) 38

else

if(preex[j] == '')

41}42while(!tmp_stack.empty())

46string str_tmp =tmp.str();

47if

(int_or_double)

52else57}

58else

67else75}

76}77if

(int_or_double)

81else

85return1;

86 }

3. 中綴轉字尾

3.1 中綴轉字尾  

①按運算子優先順序對所有的運算單位加括號

②將運算子移動到對應括號的後面

③去掉括號,得到字首表示式

(1)表示式樹

(2)棧

3.2 字尾表示式解析結算 

①從左到右掃瞄表示式

②遇到數字,數字壓棧,遇到運算子,取出棧頂兩個數做運算:次頂 op 棧頂,結果入棧

③重複,直到表示式最右側

4. 表示式合法性判斷

(1)括號的合法性

這裡的括號表示式只有 [ ] ( ) ,暫不算數字和運算子,且輸入的表示式字串裡面沒有其他無效字元

boolexpreisok()

',',,};

stackchar_stack;

stringstr;

getline(cin,str);

cout<<"your expression:"string::iterator iter =str.begin();

while(iter !=str.end())

else

}else

++iter;

}if(char_stack.empty())

else

}

(2)運算子合法性

(3)運算數合法性

5. 完整的解析計算中綴表示式

①檢驗合法性:包括括號的合法性和運算子的合法性、運算數合法性

括號合法性:括號成對出現且遵循數學規範

運算子合法性:比如不能有兩個連續的運算子

運算數合法性:這裡暫忽略大數。如果遇到小數,則運算數 3.14  5. 都是合法的,但 3.14. 不合法

②中綴轉成字首

③字首解析計算

表示式解析

1 本文目標 分析用堆疊解析算術表示式的基本方法。給出的示例 能解析任何包括 和0到9數字組成的算術表示式。2 中綴表示式和字尾表示式 中綴表示式就是通常所說的算術表示式,比如 1 2 3 4。字尾表示式是指通過解析後,運算子在運算數之後的表示式,比如上式解析成字尾表示式就是12 3 4 這種表示式...

1106 解析布林表示式 C

與波蘭表示式類似,利用2個棧,乙個存數字,乙個存運算子。略有不同的是,四則運算都是雙目運算子,每次計算都是彈出2個數字與1個運算子,結果再壓入數字棧中。但是此題的運算子 或與 都是多目運算子,遇到 要一直彈出到 用兩個變數記錄是否出現t或f,對於 只要出現false結果就是false 對於 只要出現...

查詢表示式解析

查詢表示式解析 1 ienumerablequery from s in names where s.length 5 orderby s select s.toupper 在語義上等同於如下 方法風格 基於方法 的查詢 ienumerablequery names where s s.length...