常見程式演算:: 中序式轉後序式 - OpenHome.cc

文章推薦指數: 80 %
投票人數:10人

人們平常使用的運算式,是將運算元放在運算子兩旁,例如a + b / d 這樣的式子,這稱為中序(infix)表示式;然而電腦剖析運算式時,為了有效率地. OPENHOME.CC 常見程式演算 |老掉牙 河內塔 費式數列 巴斯卡三角形 三色旗 老鼠走迷宮 騎士走棋盤 八皇后 八銀幣 康威生命遊戲 字串比對 背包問題 雙色、三色河內塔 得分排行 |「數」 最大訪客數 Eratosthenes篩選求質數 完美數 阿姆斯壯數 大數運算 指定位數的圓周率 |隨機 蒙地卡羅法求PI 洗牌 Craps賭博遊戲 約瑟夫問題 |組構 排列 格雷碼 子集 k組合 因數分解 加法因子 |排序 選擇、插入、氣泡排序 Heap排序-改良的選擇排序 Shell排序-改良的插入排序 Shaker排序-改良的氣泡排序 快速排序(一) 快速排序(二) 合併排序 基數排序 |搜尋 線性搜尋 二分搜尋 插補搜尋 費氏搜尋 |矩陣 稀疏矩陣 多維矩陣降維 上/下三角、對稱矩陣 奇數魔方陣 4N魔方陣 2(2N+1)魔方陣 |運算 中序式轉後序式 後序式運算 Quine GitHub Twitter Facebook LinkedIn Designs Tags BuiltwithbyHugo HOME> 常見程式演算> 運算> 中序式轉後序式 解法思路 程式實作 postfix infix parser computation C Java Python Scala Ruby JavaScript Haskell 中序式轉後序式 December12,2021 人們平常使用的運算式,是將運算元放在運算子兩旁,例如a+b/d這樣的式子,這稱為中序(infix)表示式;然而電腦剖析運算式時,為了有效率地判斷運算的順序,可將中序表示式轉換為後序(postfix)或前序(prefix)表示式。

解法思路 後序表示式又稱為逆向波蘭表示式(reversepolishnotation),是由波蘭的數學家盧卡謝維奇提出,例如(a+b)*(c+d),表示為後序表示式時是ab+cd+*。

想以人工轉換計算後序式的話,可以使用括號法,將運算子兩旁的運算元,依先後順序全部括號起來,然後將右括號取代為左邊最接近的運算子(從最內層括號開始),最後去掉全部的左括號就可以完成。

例如: a+b*d+c/d ((a+(b*d))+(c/d)) abd*+cd/+ 另一個方式是堆疊法,使用迴圈取出中序式的元素,遇運算元直接輸出,遇到運算子與左括號進行堆疊,堆疊中運算子優先順序若大於等於讀入的運算子優先順序,直接輸出堆疊中的運算子,再將讀入的運算子置入堆疊;遇右括號輸出堆疊中的運算子至左括號。

以下是虛擬碼的運算法,\0表示中序式讀取完畢: ProcedurePostfix(infix)[ Loop[ op=infix(i) case[ :x='\0': while(stacknotempty) //outputallelementsinstack end return :x='(': //putitintostack :xisoperator: while(priority(stack[top])>= priority(op))[ //outaelementfromstack ] //saveopintostack :x=')': while(stack(top)!='(')[ //outaelementfromstack ] top=top-1//notout'( :else: //outputcurrentop ] i++; ] ] 例如(a+b)*(c+d),依演算法的輸出過程如下: 元素 堆疊 輸出 ( ( - a ( a + (+ a b (+ ab ) - ab+ * * ab+ ( *( ab+ c *( ab+c + *(+ ab+c d *(+ ab+cd ) * ab+cd+ - - ab+cd+* 若要用堆疊法將中序式轉為前序式,使用迴圈由後往前取出中序式的字元,遇運算元直接輸出;遇運算子與右括號進行堆疊;堆疊中運算子優先順序若大於讀入的運算子優先順序,直接輸出堆疊中的運算子,再將讀入的運算子置入堆疊;遇左括號輸出堆疊中的運算子至右括號。

程式實作 C Java Python Scala Ruby JavaScript Haskell #include #include #defineMAX80 voidinToPostfix(char*,char*);//中序轉後序 intpriority(char);//運算子優先權 intmain(void){ charinfix[MAX]={'\0'}; charpostfix[MAX]={'\0'}; printf("中序運算式:"); scanf("%s",infix); inToPostfix(infix,postfix); inti; for(i=0;postfix[i]!='\0';i++){ printf("%c",postfix[i]); } return0; } voidinToPostfix(char*infix,char*postfix){ charstack[MAX]={'\0'}; inti,j,top; for(i=0,j=0,top=0;infix[i]!='\0';i++)switch(infix[i]){ case'('://運算子堆疊 stack[++top]=infix[i]; break; case'+':case'-':case'*':case'/': while(priority(stack[top])>=priority(infix[i])){ postfix[j++]=stack[top--]; } stack[++top]=infix[i];//存入堆疊 break; case')': while(stack[top]!='('){//遇)輸出至( postfix[j++]=stack[top--]; } top--;//不輸出( break; default://運算元直接輸出 postfix[j++]=infix[i]; } while(top>0){ postfix[j++]=stack[top--]; } } intpriority(charop){ switch(op){ case'+':case'-':return1; case'*':case'/':return2; default:return0; } } importjava.util.*; importstaticjava.lang.System.out; publicclassInfix{ privatestaticintpriority(charc){ returnc=='+'||c=='-'?1:c=='*'||c=='/'?2:0; } privatestaticStringtoPostfix(Stringinfix,booleanisPost){ Stringexpr=isPost? infix:newStringBuffer(infix).reverse().toString(); LinkedListstack=newLinkedList<>(); StringBuilderoutput=newStringBuilder(); chartoStack=isPost?'(':')'; chartoOutput=isPost?')':'('; for(charc:expr.toCharArray()){ if(c==toStack){stack.add(c);} elseif("+-*/".indexOf(c)!=-1){ while(!stack.isEmpty()&& priority(stack.getLast())>=priority(c)){ output.append(stack.removeLast()); } stack.add(c); } elseif(c==toOutput){ while(stack.getLast()!=toStack){ output.append(stack.removeLast()); } stack.removeLast(); } else{output.append(c);} } while(!stack.isEmpty()){output.append(stack.removeLast());} returnisPost?output.toString():output.reverse().toString(); } publicstaticStringtoPostfix(Stringinfix){ returntoPostfix(infix,true); } publicstaticStringtoPrefix(Stringinfix){ returntoPostfix(infix,false); } publicstaticvoidmain(String[]args){ Stringinfix="(a+b)*(c+d)"; out.println(toPostfix(infix)); out.println(toPrefix(infix)); } } defpriority(op): return1ifopin"+-"else2ifopin"*/"else0 deftoPostfix(infix,isPost=True): toStack,toOutput=('(',')')ifisPostelse(')','(') defprocOpt(c,stack,output): ifstack==""orpriority(stack[-1])1 case'*'|'/'=>2 case_=>0 } deftoPostfix(infix:String,isPost:Boolean=true)={ val(toStack,toOutput)=if(isPost)('(',')')else(')','(') defprocOpt(c:Char,stack:String,output:String):(String,String)={ if(stack==""||priority(stack.last)(c,stack,output){ ifstack==""||priority(stack[-1])(stack,output){ ifstack[-1]==toStack [stack[0...-1],output] else procPhs.call(stack[0...-1],output+stack[-1]) end } procExpr=->(expr,stack="",output=""){ ifexpr=="" output+stack.reverse elsifexpr[0]==toStack procExpr.call(expr[1..-1],stack+expr[0],output) elsif"+-*/".include?expr[0] procExpr.call(expr[1..-1],*procOpt.call(expr[0],stack,output)) elsifexpr[0]==toOutput procExpr.call(expr[1..-1],*procPhs.call(stack,output)) else procExpr.call(expr[1..-1],stack,output+expr[0]) end } output=procExpr.call(isPost?infix:infix.reverse) isPost?output:output.reverse end deftoPrefix(infix) toPostfix(infix,false) end infix="(a+b)*(c+d)" puts(toPostfix(infix)) puts(toPrefix(infix)) Array.prototype.getLast=function(){ returnthis[this.length-1]; }; Array.prototype.isEmpty=function(){ returnthis.length==0; }; functionpriority(c){ returnc==='+'||c==='-'?1:c==='*'||c==='/'?2:0; } functiontoPostfix(infix,isPost){ isPost=isPost===undefined?true:false; varexpr=isPost?infix.split(''):infix.split('').reverse(); varstack=[]; varoutput=[]; vartoStack=isPost?'(':')'; vartoOutput=isPost?')':'('; expr.forEach(function(c){ if(c===toStack){stack.push(c);} elseif('+-*/'.indexOf(c)!==-1){ while(!stack.isEmpty()&& priority(stack.getLast())>=priority(c)){ output.push(stack.pop()); } stack.push(c); } elseif(c===toOutput){ while(stack.getLast()!==toStack){ output.push(stack.pop()); } stack.pop(); } else{output.push(c);} }); while(!stack.isEmpty()){output.push(stack.pop());} returnisPost?output.join(''):output.reverse().join(''); } functiontoPrefix(infix){ returntoPostfix(infix,false); } varinfix="(a+b)*(c+d)"; print(toPostfix(infix)); print(toPrefix(infix)); priorityop=ifop`elem`"+-"then1 elseifop`elem`"*/"then2 else0 toPfixinfisPost=ifisPostthenoutputelsereverseoutput where (toStack,toOutput)=ifisPostthen('(',')')else(')','(') output=procExpr(ifisPosttheninfelsereverseinf)("","") procOptcstackoutput= ifstack==""||(priority$laststack)



請為這篇文章評分?