Skip to content

Commit edf5673

Browse files
committed
Algorithm explanation
1 parent 0d82baf commit edf5673

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed

Shunting Yard/README.markdown

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# Shunting Yard Algorithm
2+
3+
Any mathematical expression that we write is expressed in a notation known as Infix Notation.
4+
5+
For example:
6+
7+
A + B * C
8+
9+
In the above expression the operator is placed between operands hence the expression is said to be in Infix form.
10+
If you think about it any expression that you write on a piece of paper will always be in infix form. This is what we humans understand.
11+
12+
Now, think about the way the above expression is evaluated, you would first multiply B and C then add the result to A. This is because multiplication has
13+
higher precedence than addition. We humans can easily understand the precedence of operators, but a machine needs to be given instructions about each operator. If you were to
14+
write an algorithm than parsed and evaluated the infix notation you'll soon realize that it's a tedious process. You'd have to parse the expression
15+
multiple times to know what operation to perform first. As the number of operators increase so does the complexity.
16+
17+
## Postfix notations / Reverse Polish Notation
18+
19+
An expression when represented in postfix form will not have any brackets and neither will you have to worry about scanning for operator precedence. This makes it easy for the computer to evaluate
20+
expressions since the order in which the operator need to be applied is fixed.
21+
22+
For example:
23+
24+
**A B C * +**
25+
26+
The above is the postfix representation of the example in the previous section. The operators come after the corresponding operands.
27+
28+
### Evaluating a postfix expression
29+
30+
A stack is used to evaluate a postfix expression. Here is the pseudocode:
31+
32+
1. read postfix expression token by token
33+
2. if the token is an operand, push it
34+
into the stack
35+
3. if the token is a binary operator,
36+
3.1 pop the two top most operands
37+
from the stack
38+
3.2 apply the binary operator with the
39+
two operands
40+
3.3 push the result into the stack
41+
4. finally, the value of the whole postfix
42+
expression remains in the stack
43+
44+
Using the above psuedocode the evaluation on the stack would be as follows:
45+
46+
| Expression | Stack |
47+
| ------------- | --------|
48+
| A B C * + | |
49+
| B C * + | A |
50+
| C * + | A, B |
51+
| * + | A, B, C |
52+
| + | A, D |
53+
| | E |
54+
55+
Where **D = B * C** and **E = A + D.**
56+
57+
As seen above a postfix operation is relatively easy to evaluate as the order in which the operators need to be applied is predecided.
58+
59+
## Shunting yard algorithm
60+
61+
The Shunting yard algorithm was invented by Edsger Dijkstra to convert an infix expression to postfix. Many calculators use this algorithm to convert the expression being entered to postfix form.
62+
63+
Here is the psedocode of the algorithm:
64+
65+
1. For all the input tokens
66+
1. Read the next token
67+
2. If token is an operator (x)
68+
1. While there is an operator (y) at the top of the operators stack and either (x) is left-associative and its precedence is less or equal to that of (y), or (x) is right-associative and its precedence is less than (y)
69+
1. Pop (y) from the stack
70+
2. Add (y) output buffer
71+
2. Push (x) on the stack
72+
3. Else If token is left parenthesis, then push it on the stack
73+
4. Else If token is a right parenthesis
74+
1. Until the top token (from the stack) is left parenthesis, pop from the stack to the output buffer
75+
2. Also pop the left parenthesis but don’t include it in the output buffer
76+
7. Else add token to output buffer
77+
2. While there are still operator tokens in the stack, pop them to output
78+
79+
### How does it work
80+
81+
Let's take a small example and see how the psuedocode works.
82+
83+
**4 + 4 * 2 / ( 1 - 5 )**
84+
85+
| Operator | Precedence | Associativity |
86+
| ---------| -------------| ----------------|
87+
| ^ | 10 | Right |
88+
| * | 5 | Left |
89+
| / | 5 | Left |
90+
| + | 0 | Left |
91+
| - | 0 | Left |
92+
93+
The above table describes the precedence and the associativity for each operator. The same values are used in the algorithm.
94+
95+
| Token | Action | Output | Operator stack |
96+
|-------|---------------------------------------------|-------------------|----------------|
97+
| 3 | Add token to output | 4 | |
98+
| + | Push token to stack | 4 | + |
99+
| 4 | Add token to output | 4 4 | + |
100+
| * | Push token to stack | 4 4 | * + |
101+
| 2 | Add token to output | 4 4 2 | * + |
102+
| / | * Pop stack to output * Push token to stack | 4 4 2 * | / + |
103+
| ( | Push token to stack | 4 4 2 * | ( / + |
104+
| 1 | Add token to output | 4 4 2 * 1 | ( / + |
105+
| - | Push token to stack | 4 4 2 * 1 | - ( / + |
106+
| 5 | Add token to output | 4 4 2 * 1 5 | - ( / + |
107+
| ) | * Pop stack to output * Pop stack | 4 4 2 * 1 5 - | / + |
108+
| end | Pop entire stack to output | 4 4 2 * 1 5 - / + | |

0 commit comments

Comments
 (0)