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中元素,得到字首表示式
1string 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,charop)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...