後綴表達式,又稱逆波蘭式,指的是不包含括弧,運算符放在兩個運算對象的後面,所有的計算按運算符出現的順序,嚴格從左向右進行(不再考慮運算符的優先規則)。
基本介紹
- 中文名:後綴表達式
- 學科:數學
- 對象:運算符
- 別稱:後綴或者逆波蘭
計算
轉換
代碼
c++代碼
#include <stack>#include <vector>#include <iostream>#include <algorithm>using namespace std;bool isOper(char c)//判斷是否為操作符{ if ((c == '+ ') || (c == '- ') || (c == '* ') || (c == '/ ') || (c == '( ') || (c == ') ')) return true; return false;}bool isHigh(char top_op, char InfixExp_op)//判斷操作符的優先權//top_op為棧頂操作符//InfixExp_op為當前讀入操作符//如果棧頂操作符優先權高,則彈出棧頂操作符//如果棧頂操作符優先權低,則壓入當前讀入操作符{ if ((top_op == '+ ') && (InfixExp_op == '+ ')) return true; if ((top_op == '+ ') && (InfixExp_op == '- ')) return true; if ((top_op == '- ') && (InfixExp_op == '+ ')) return true; if ((top_op == '- ') && (InfixExp_op == '- ')) return true; if ((top_op == '* ') && (InfixExp_op == '+ ')) return true; if ((top_op == '* ') && (InfixExp_op == '- ')) return true; if ((top_op == '* ') && (InfixExp_op == '* ')) return true; if ((top_op == '* ') && (InfixExp_op == '/ ')) return true; if ((top_op == '/ ') && (InfixExp_op == '+ ')) return true; if ((top_op == '/ ') && (InfixExp_op == '- ')) return true; if ((top_op == '/ ') && (InfixExp_op == '* ')) return true; if ((top_op == '/ ') && (InfixExp_op == '/ ')) return true; if (InfixExp_op == ') ') return true; return false;}void input(vector <char> *InfixExp){ char c; cin >> c; while (c != '$ ') { InfixExp->push_back(c); cin >> c; }}void output(vector <char> *postfixExp){ vector <char> ::iterator postfixExp_it;//後綴表達式疊代器 for (postfixExp_it = postfixExp->begin(); postfixExp_it != postfixExp->end(); postfixExp_it++) cout << *postfixExp_it << " "; cout << endl;}void output2(vector <char> *postfixExp)//不輸出括弧//如果表達式中括弧不配對//則可能有多餘的括弧未彈出{ vector <char> ::iterator postfixExp_it;//後綴表達式疊代器 for (postfixExp_it = postfixExp->begin(); postfixExp_it != postfixExp->end(); postfixExp_it++) { if ((*postfixExp_it != '( ') && (*postfixExp_it != ') ')) cout << *postfixExp_it << " "; } cout << endl;}void main(){ stack <char> mystack; vector <char> InfixExp;//中綴表達式 vector <char> ::iterator InfixExp_it;//中綴表達式疊代器 vector <char> postfixExp;//後綴表達式 do { cout << "Please input a formula, ended by $: " << endl; input(&InfixExp); //輸入表達式 output(&InfixExp); for (InfixExp_it = InfixExp.begin(); InfixExp_it != InfixExp.end(); InfixExp_it++) { if (!isOper(*InfixExp_it)) //運算元,直接輸出 postfixExp.push_back(*InfixExp_it); else //操作符 { if (mystack.empty()) //棧為空,壓入操作符 mystack.push(*InfixExp_it); else if (isHigh(mystack.top(), *InfixExp_it)) //棧頂操作符優先,比如棧頂為*,當前操作符為+,則彈出* { if (*InfixExp_it != ') ') //非閉括弧 //彈出棧中操作符直到棧頂運算元優先權低於當前讀入運算元 //壓入當前讀入操作符 { do { postfixExp.push_back(mystack.top()); mystack.pop(); } while ((!mystack.empty()) && (isHigh(mystack.top(), *InfixExp_it))); mystack.push(*InfixExp_it); } else //閉括弧 { while ((!mystack.empty()) && (mystack.top() != '( ')) //彈出直到開括弧 { postfixExp.push_back(mystack.top()); mystack.pop(); } if ((!mystack.empty()) && (mystack.top() == '( ')) mystack.pop(); //彈出開括弧 } } else if (!isHigh(mystack.top(), *InfixExp_it)) //中綴表達式中操作符優先 //比如棧頂為+,而當前讀入* { mystack.push(*InfixExp_it); //壓入當前讀入操作符 } } } while (!mystack.empty()) //把棧中剩餘的操作符依次彈出 { postfixExp.push_back(mystack.top()); mystack.pop(); } output2(&postfixExp); while (!mystack.empty()) mystack.pop(); InfixExp.clear(); postfixExp.clear(); //清空棧、中綴表達式和後綴表達式 } while (true);}
pascal代碼
program p2_29;const max=100; op_set:set of char=['+','-','*','/']; letter:set of char=['0'..'9'];var expression,result:string; procedure sean(expression:string);var i,top1,top2:integer; ovs:array [1..max] of string[max]; ops:array [1..max] of char; f:array ['#'..'/','#'..'/'] of shortint;begin f['+','+']:=1; f['+','-']:=1; f['+','*']:=-1; f['+','/']:=-1; f['+','(']:=-1; f['+',')']:=1; f['+','#']:=1; f['-','+']:=1; f['-','-']:=1; f['-','*']:=-1; f['-','/']:=-1; f['-','(']:=-1; f['-',')']:=1; f['-','#']:=1; f['*','+']:=1; f['*','-']:=1; f['*','*']:=1; f['*','/']:=1; f['*','(']:=-1; f['*',')']:=1; f['*','#']:=1; f['/','+']:=1; f['/','-']:=1; f['/','*']:=1; f['/','/']:=1; f['/','(']:=-1; f['/',')']:=1; f['/','#']:=1; f['(','+']:=-1; f['(','-']:=-1; f['(','*']:=-1; f['(','/']:=-1; f['(','(']:=-1; f['(',')']:=0; f['(','#']:=2; f[')','+']:=2; f[')','-']:=2; f[')','*']:=2; f[')','/']:=2; f[')','(']:=2; f[')',')']:=2; f[')','#']:=2; f['#','+']:=-1; f['#','-']:=-1; f['#','*']:=-1; f['#','/']:=-1; f['#','(']:=-1; f['#',')']:=2; f['#','#']:=0; {優先權設定} expression:=expression+'#';{末尾加標誌} ops[1]:='#'; top1:=0; top2:=1; for i:=1 to length(expression) do {逐個掃描} begin if expression[i] in letter then {是數字就進棧} begin inc(top1); ovs[top1]:=expression[i]; end else begin {運算符} while f[ops[top2],expression[i]]=1 do {棧頂運算符優先權高於當前運算符} begin {取棧頂上面的兩個元素運算後,再壓棧} ovs[top1-1]:=ovs[top1-1]+ovs[top1]+ops[top2]; top1:=top1-1; dec(top2); end; if f[ops[top2],expression[i]]=0 then top2:=top2-1 {優先權相同,則抵消} else {棧頂運算符優先權低於當前運算符,則壓棧} begin top2:=top2+1; ops[top2]:=expression[i]; end; end; end; result:=ovs[1];{返回結果}end;begin readln(expression); sean(expression); writeln(result); readln;
Java代碼
/** * 後序遍歷遞歸實現 * * 左 右 中 * @param node */ public void nextOrder(Node node) { if (node == null) { return; } nextOrder(node.left); nextOrder(node.right); System.out.println(node.data); } /** * 後序遍歷非遞歸實現 * @param node */ public void nextOrder2(Node node) { if (node == null) { return; } Stack<Node> stack = new Stack<>(); Node p = node; while (node != null) { while (node.left != null) { stack.push(node); node = node.left; } while (node != null && (node.right == null || node.right == p)) { System.out.println(node.data); p = node; if (stack.isEmpty()) { return; } node = stack.pop(); } stack.push(node); node = node.right; } }
求值
program p2_30a;const maxn=20;var stack:array [1..maxn] of integer; s:string; function comp(s:string):integer;var ch:char; i,top,x,y,z:integer;begin top:=0; i:=1; ch:=s[i]; while i<=length(s) do {逐個位數判斷} begin case ch of '0'..'9':begin x:=0; while (ch<>' ') do begin x:=x*10+ord(ch)-ord('0'); {當前數位} i:=i+1; ch:=s[i];{下一位} end; inc(top); stack[top]:=x; end; '+':begin x:=stack[top]; dec(top); y:=stack[top];{獲得兩個數} z:=y+x; {計算} stack[top]:=z; {存值} end; '-':begin x:=stack[top]; dec(top); y:=stack[top];{獲得兩個數} z:=y-x; {計算} stack[top]:=z; {存值} end; '*':begin x:=stack[top]; dec(top); y:=stack[top];{獲得兩個數} z:=y*x; {計算} stack[top]:=z; {存值} end; '/':begin x:=stack[top]; dec(top); y:=stack[top];{獲得兩個數} z:=y div x; {計算} stack[top]:=z; {存值} end; end; inc(i); ch:=s[i]; end; exit(stack[top]);end;begin readln(s); writeln(comp(s)); readln;end.