排程場演算法（Shunting Yard Algorithm）是一個用於將中綴表示式轉換為字尾表示式的經典演算法，由艾茲格迪傑斯特拉引入，因其操作類似於火車編組場而得名。 簡例 輸入：34 將 3 入輸出佇列（每當輸入一個數字時，直接進入輸出佇列） 將 號壓入運算堆疊 將 4 入輸出佇列 輸入結束，將運算子堆疊中剩餘運算子入輸出佇列 在本情況下只有 號 輸出 透過這個例子可以看出兩條規則： 當讀入一個數字時直接入輸出佇列 當輸入結束後，運算子佇列中所有運算子入輸出佇列 詳細的演算法 當還有記號可以讀取時： 讀取一個記號。 如果這個記號表示一個數字，那麼將其新增到輸出佇列中。 如果這個記號表示一個函式，那麼將其壓入棧當中。 如果這個記號表示一個函式引數的分隔符（例如，一個半形逗號，）： 從棧當中不斷地彈出運算子並且放入輸出佇列中去，直到棧頂部的元素為一個左括號為止。如果一直沒有遇到左括號，那麼要麼是分隔符放錯了位置，要麼是括號不匹配。 如果這個記號表示一個運算子，記做 o1，那麼： 只要存在另一個記為 o2 的運算子位於棧的頂端，並且 如果 o1 是左結合性的並且它的運算子優先順序要小於或者等於 o2 的優先順序，或者 如果 o1 是右結合性的並且它的運算子優先順序比 o2 的要低，那麼 將 o2 從棧的頂端彈出並且放入輸出佇列中（迴圈直至以上條件不滿足為止）； 然後，將 o1 壓入棧的頂端。 如果這個記號是一個左括號，那麼就將其壓入棧當中。 如果這個記號是一個右括號，那麼： 從棧當中不斷地彈出運算子並且放入輸出佇列中，直到棧頂部的元素為左括號為止。 將左括號從棧的頂端彈出，但並不放入輸出佇列中去。 如果此時位於棧頂端的記號表示一個函式，那麼將其彈出並放入輸出佇列中去。 如果在找到一個左括號之前棧就已經彈出了所有元素，那麼就表示在表示式中存在不匹配的括號。 當再沒有記號可以讀取時： 如果此時在棧當中還有運算子： 如果此時位於棧頂端的運算子是一個括號，那麼就表示在表示式中存在不匹配的括號。 將運算子逐個彈出並放入輸出佇列中。 退出演算法。 更詳細的例子 中綴表示法 及 結果： 逆波蘭表示法： 輸入 3 4 2 1 5 2 3 輸入 動作 輸出 逆波蘭表示法 運算子堆疊 提示 3 將符號加入輸出佇列 3 將符號壓入運算子堆疊 3 4 將符號加入輸出佇列 3 4 將符號壓入運算子堆疊 3 4 號的優先順序高於 號 2 將符號加入輸出佇列 3 4 2 將堆疊中元素彈出，加入輸出佇列 3 4 2 號和 號優先順序相同 將符號壓入運算子堆疊 3 4 2 號的優先順序高於 號 將符號壓入運算子堆疊 3 4 2 1 將符號加入輸出佇列 3 4 2 1 將符號壓入運算子堆疊 3 4 2 1 5 將符號加入輸出佇列 3 4 2 1 5 將堆疊中元素彈出，加入輸出佇列 3 4 2 1 5 迴圈直到找到 號 將堆疊元素彈出 3 4 2 1 5 括號匹配結束 將符號壓入運算子堆疊 3 4 2 1 5 號的優先順序高於 號 2 將符號加入輸出佇列 3 4 2 1 5 2 將符號壓入運算子堆疊 3 4 2 1 5 2 號為從右至左求值 3 將符號加入輸出佇列 3 4 2 1 5 2 3 END 將棧中所有資料加入輸出佇列 3 4 2 1 5 2 3 C 程式實現 include cstring include cstdio define op_left_assoc c c c c c c define is_operator c c c c c c c c define is_function c c A c Z define is_ident c c 0 c 9 c a c z 運算子 優先順序 符號 運算順序 1 從右至左 2 從左至右 3 從左至右 4 從右至左 int op_preced const char c switch c case return 4 case case case return 3 case case return 2 case return 1 若輸入不是運算子 return 0 unsigned int op_arg_count const char c switch c 運算子 case case case case case case return 2 階乘 case return 1 不是運算子 default return c A return 0 bool shunting_yard const char input char output const char strpos input strend input strlen input char c stack 32 sc outpos output unsigned int sl 0 while strpos strend c strpos if c 掃描到左括號直接入棧 if c stack sl c sl 如果輸入為數字，則直接入輸出佇列 else if is_ident c outpos c outpos 如果輸入為函式記號，則壓入堆疊 else if is_function c stack sl c sl 如果輸入為函式分割符（如：逗號） else if c bool pe false while sl 0 sc stack sl 1 掃描到左括號 跳出輸出迴圈，此時左括號作為函式邊界判定，所以不出棧 if sc pe true break else 棧頂元素不是左括號 將棧頂元素依次出棧並放入輸出佇列 outpos sc outpos sl 如果沒有遇到左括號，則有可能是符號放錯或者不匹配 if pe printf Error separator or parentheses mismatchedn return false 如果輸入符號為運算子，然後 else if is_operator c while sl 0 sc stack sl 1 sc 為其棧頂元素 如果 c 是左結合性的且它的優先順序小於等於棧頂運算子 sc 的優先順序 或者 c 是右結合性且它的優先順序小於棧頂運算子 sc 的優先順序 將棧頂元素 sc 出棧，否則 sc 進棧 if is_operator sc op_left_assoc c op_preced c op_preced sc op_left_assoc c op_preced c op_preced sc outpos sc outpos sl else break c 的優先順序大於或大於等於結合性的要求，則將其入棧 stack sl c sl 掃描到右括號 else if c bool pe false 從棧頂向下掃描左括號，將掃描到左括號之前的棧頂運算子出棧並放入輸出佇列 while sl 0 sc stack sl 1 if sc pe true break else outpos sc outpos sl 如果沒有掃描到左括號，則有可能是符號放錯或者不匹配 if pe printf Error parentheses mismatchedn return false 左括號出棧且不放入輸出佇列 sl 掃描完左括號後 如果棧頂元素是函式運算子 則將其出棧並放入輸出佇列 if sl 0 sc stack sl 1 if is_function sc outpos sc outpos sl 未知運算子 c else printf Unknown token cn c strpos 當所有元素已經讀完 棧中還有剩餘運算子 while sl 0 sc stack sl 1 如果剩餘括號，則符號放錯或者不匹配 if sc sc printf Error parentheses mismatchedn return false 出棧並放入輸出佇列 outpos sc outpos sl outpos 0 指標置零 return true bool execution_order const char input printf order arguments in reverse ordern const char strpos input strend input strlen input char c res 4 unsigned int sl 0 sc stack 32 rn 0 While there are input tokens left while strpos strend Read the next token from input c strpos If the token is a value or identifier if is_ident c Push it onto the stack stack sl c sl Otherwise the token is an operator operator here includes both operators and functions else if is_operator c is_function c sprintf res _02d rn printf s res rn It is known a priori that the operator takes n arguments unsigned int nargs op_arg_count c If there are fewer than n values on the stack if sl nargs return false Error The user has not input sufficient values in the expression Else Pop the top n values from the stack Evaluate the operator with the values as arguments if is_function c printf c c while nargs 0 sc stack sl 1 sl if nargs 1 printf s sc else printf sn sc nargs else if nargs 1 sc stack sl 1 sl printf c sn c sc else sc stack sl 1 sl printf s c sc c sc stack sl 1 sl printf sn sc Push the returned results if any back onto the stack stack sl unsigned int res sl strpos If there is only one value in the stack That value is the result of the calculation if sl 1 sc stack sl 1 sl printf s is a resultn sc return true If there are more values in the stack Error The user input has too many values return false int main functions A B a C a b D a b c identifiers 0 1 2 3 and a b c d e operators const char input a D f b c d e g char output 128 printf input sn input if shunting_yard input output printf output sn output if execution_order output printf nInvalid inputn return 0 參見 中綴表示式 字尾表示式 Category 分析演演算法 Category 荷蘭發明