One common application of a stack to find the value of a
postfix expression. First, let's explain the terminology. An infix expression
is the type that we are used to in ordinary algebra, such as 3 + 9, which is an expression
representing the sum of 3 and 9. Infix expressions place their (binary)
operators between the two values to which they apply. In the above example, the
addition operator was placed between the 3 and the 9.
A postfix expression, in
contrast, places each operator after the two values to which it applies. (Post means "after", right?) The
above expression would be 3 9 +, when rewritten in postfix. Here
are a few more examples in the following table. The infix form is shown on the
left, and the postfix form is given on the right.
|
Infix: |
Postfix: |
|
16 / 2 |
16 2 / |
|
(2 + 14)
* 5 |
2 14 + 5
* |
|
2 + 14 *
5 |
2 14 5 *
+ |
|
(6 - 2) *
(5 + 4) |
6 2 - 5 4
+ * |
Note that postfix
expressions do not use parentheses for grouping; it is not needed! Infix sometimes
requires parentheses to force a certain order of evaluation. For example, in
the second example above, parentheses were needed to indicate that the addition
should be done before the multiplication. Without the parentheses you get the
third example, where the multiplication is done before the addition (using the
precedence rules from ordinary arithmetic, or from C++, for that matter).
Arithmetic expressions like
the above can of course be much longer. We could also allow other operators,
such as ^ for exponentiation, or perhaps a unary minus. A sample infix
expression that uses exponentiation is 4 ^ 2,
which means 4 to the second power. A unary minus is sometimes used as in the
infix expression -(4 + 2). A unary
operator is one that is applied to a single value, as opposed
to the typical binary operators, which are applied to two values. We will not
consider unary operators or exponentiation further here.
The algorithm to evaluate a
postfix expression works like this: Start with an empty stack of integers. Scan
the postfix expression from left to right. Whenever you reach a number, push it
onto the stack. Whenever you reach an operator (call it Op perhaps), pop two
items, say First and Second, and then push the value obtained using Second Op First. When you reach the end of the postfix expression,
pop a value from the stack. That value should be the correct answer, and the
stack should now be empty. (If the stack is not empty, the expression was not a
correct postfix expression.)
Let's look at the postfix
expression evaluation algorithm by way of example. Consider the postfix
expression 2 14 + 5 * that was mentioned above. We
already know from its infix form, (2
+ 14) * 5, that
the value should be 16 * 5 = 80. The following sequence of pictures
depicts the operation of the algorithm on this example. Read through the
pictures from left to right.
![[postfix evaluation drawing]](assign1_files/image001.gif)
Let's evaluate another
postfix expression, say 2 10 + 9 9
- /, which is (2 + 10) / (9 - 6) in infix. Clearly the value should
work out to be 12 / 3 = 4. Trace through the algorithm by
reading the following pictures from left to right.
![[postfix evaluation drawing]](assign1_files/image002.gif)
When one reaches an
operator in this algorithm, it is important to get the order right for the
values to which it applies. The second item popped off should go in front of
the operator, while the first one popped off goes after the operator. You can
easily see that with subtraction and division the order does matter.
Assignment: Develop a C++ program that
repeatedly evaluates postfix integer expressions with the 4 operators +, -,
/. *. Where / is integer division. It should print out the current value at
the top of the stack when encountering a p and quit when encountering a q.
Hints:
Xtra credit check for input errors and handle
exceptions.