Data Structures - Intercollege Cyprus

Download Report

Transcript Data Structures - Intercollege Cyprus

Andreas Savva
Data Structures
Chapter 13
The Polish Notation
(Application of Stacks)
Polish Notation


Evaluation of arithmetic expressions
The Problem:


One of the most important accomplishments of early
design computer languages was allowing programmers
to write arithmetic expressions in something close to
their usual mathematical form.
It was a real achievement to design a compiler that
understood expressions such as:
(x + y) * exp(x – z) – 4.0
a*b + c/d – c * (x+y)
not (p and q) or (x<=7.0)
and produce machine-language output. In fact, the name
FORTRAN stands for FORMULA TRANSLATOR
2
Important of the Polish Notation



It is not necessary to make repeated scans
through the expression
No parentheses used
Evaluation can be achieved with great
efficiency
3
The Quadratic formula
 b  b  4ac
x
2a
2
x := (-b + (b^2 – (4 * a) * c)^0.5) / (2 * a)
Question

Which operation must be done before others.

What are the effects of the parentheses? When
can they omitted?

How many times you will look back and forth
through the expression until you evaluate it?
4
Compiler Convensions


Priorities
1.
^
2.
*
3.
+ –
/
Operations are ordinarily done left to right.
x = (-b + (b^2 – (4 * a) * c)^0.5) / (2 * a)
10
1
7
2
5
3
4
6
9
8
5
C++ operation priorities
Binary operators
1. * / %
2. + –
3. < <= > >=
4. == !=
5. &&
6. ||
7. =
Unary operators

-5

+5

+ –5 = –5

– –5 = 5
6
Polish Notation


Discovered by the polish mathematician
Jan Lukasiewicz.
Operators are either before or after their
operands:
before  prefix
after  postfix
Note:
between  infix
7
Examples
ab
prefix   a b
postfix  a b 
infix  a  b
a+bc
prefix  + a  b c
postfix  a b c  +
Note:
Prefix and Postfix are not
mirror to each other
8
Prefix – Polish notation
Postfix – Reverse polish notation

Change the following expression to
a)
b)
Reverse Polish notation
Polish notations
3 + (4 + 6  2)  ((8 – 3)  (2 - 5) + 4) – 2  6
a)
Reverse Polish Notation:
3 4 6 2  + 8 3 – 2 5 –  4 +  + 2 6  –
b)
Polish Notation:
– + 3  + 4  6 2 +  – 8 3 – 2 5 4  2 6
9
Reverse Polish Notation

Note:
5 4
6 
+
 Error
 Error
 Error
5 –
 Unary operator
Use a different symbol to represent unary operators, i.e. (~)
(-5) – (-4)  5 ~ 4 ~ –
10
Converting Infix to Postfix with Stack

Read expression from Left-to-Right and






if an operand is read copy it to the output,
if a left parenthesis is read push it into the stack,
when a right parenthesis is encountered, the operator at the top of
the stack is popped off the stack and copied to the output until the
symbol at the top of the stack is a left parenthesis. When that occurs,
both parentheses are discarded,
if an operator is scanned and has a higher precedence than the
operator at the top of the stack, the operator being scanned is pushed
onto the stack,
while the precedence of the operator being scanned is lower than or
equal to the precedence of the operator at the top of the stack, the
operator at the top of the stack is popped and copied to the output,
when the end of the expression is reached on the input scan, the
remaining operators in the stack are popped and copied to the output.
11
Example
Input:
4 * (2 – (6 * 3 + 4) * 2) + 1
Output: 4
2 6
3 * 4
*
(
+
–
(
–
(
*
–
(
*
*
*
(
+ 2
*
* –
* 1
+
+
12
Converting Infix to Prefix with Stack

Read expression from Right-to-Left and






if an operand is read copy it to the LEFT of the output,
if a right parenthesis is read push it into the stack,
when a left parenthesis is encountered, the operator at the top of the
stack is popped off the stack and copied to the LEFT of the output
until the symbol at the top of the stack is a right parenthesis. When
that occurs, both parentheses are discarded,
if an operator is scanned and has a higher or equal precedence than
the operator at the top of the stack, the operator being scanned is
pushed onto the stack,
while the precedence of the operator being scanned is lower than to
the precedence of the operator at the top of the stack, the operator at
the top of the stack is popped and copied to the LEFT of the output,
when the end of the expression is reached on the input scan, the
remaining operators in the stack are popped and copied to the LEFT
of the output.
13
Example
Input:
4 * (2 – (6 * 3 + 4) * 2) + 1
Output: + * 4
– 2 *
+ *
*
)
*
)
–
)
*
+
+
+
+
6 3
4 2
1
*
+
)
14
Converting Infix to Prefix with Stack
2nd method


Reverse the expression
Read expression from Left-to-Right and







if an operand is read copy it to the output (left-to-right),
if a right parenthesis is read push it into the stack,
when a left parenthesis is encountered, the operator at the top of the
stack is popped off the stack and copied to the output until the
symbol at the top of the stack is a right parenthesis. When that
occurs, both parentheses are discarded,
if an operator is scanned and has a higher or equal precedence than
the operator at the top of the stack, the operator being scanned is
pushed onto the stack,
while the precedence of the operator being scanned is lower than to
the precedence of the operator at the top of the stack, the operator at
the top of the stack is popped and copied to the output,
when the end of the expression is reached on the input scan, the
remaining operators in the stack are popped and copied to the output.
Reverse the output
15
Example
Input:
4 * (2 – (6 * 3 + 4) * 2) + 1
Reverse: 1 + ) 2 * ) 4 + 3 * 6 ( – 2 ( * 4
Output:
1 2 4 3
6
* + *
2 – 4 * +
*
+
)
*
)
*
)
–
)
*
+
+
+
+
Reverse Output:
+ * 4
–
2 * + * 6 3 4 2 1
16
Exercises

Using stack diagrams convert the following
expressions into postfix and prefix forms of
polish notation:
a)
b)
c)
d)
e)
f)
g)
8–34+2
8 – 3  (4 + 2)
(8 – 3)  (4 + 2)
(8 – 3)  4 + 2
(-a + b)  (c + a) – 5
2 + ((-3 + 1)  (4 – 2) + 3)  6 – (1 + 2  3)
(5 > 4) and not (3 = 2 – 1)
17
Evaluation of Reverse Polish
Expressions


Most compilers use the polish form to translate
expressions into machine language.
Evaluation is done using a stack data-structure



Read expression from left to right and build the stack of
numbers (operands).
When an operator is read two operands are popped out
of the stack they are evaluated with the operator and the
result is pushed into the stack.
At the end of the expression there must be only one
operand into the stack (the solution) otherwise ERROR.
18
3 4 6 2  + 8 3 – 2 5 –  4 +  + 2 6  –
4 + 12
62
2
6
4
3
3
8
16
3
12
4
3
5  (-3)
-3
5
16
3
8–3
2–5
16  (-11)
-15 + 4
4
-15
16
3
5
2
5
16
3
-11
16
3
-173 – 12
26
3 + (-176)
-176
6
2
12
3
-173
-173
Result = -185
19
Evaluation of Polish Expressions

Evaluation is done using a stack data-structure



Read expression from right to left and build the stack of
numbers (operands).
When an operator is read two operands are popped
out of the stack they are evaluated with the operator
and the result is pushed into the stack.
At the end of the expression there must be only one
operand into the stack (the solution) otherwise ERROR.
20
–  3 – 8  3 2 – ~ 4 – 6 2
-4
6–2
6
2
32
8–6
8
6
-8
3
2
-8
-4
4
4
4
32
-4 – 4
6 – (-8)
3
2
6
-8
-8
Result = 14
21
Running-sum condition

For a sequence E of operands, unary operators and
binary operators, form a running-sum by starting at
the left-end of E and counting




+1 for each operand,
0 for unary operator, and
–1 for each binary operator.
E satisfies the running-sum condition provided that
it never falls below 1, and is exactly 1 at the righthand-end of E.
3 4 6 2  + 8 3 – 2 5 –  4 +  + 2 6  –
22
Exercises
1. Which of the following are syntactically correct
postfix expressions (use the running-sum
condition)? Show the error in each incorrect
expression. Translate each correct expression into
infix form.
a) a b c +  a / c b + d / –
b) a b + c a  b c / d –
c) a b + c a  – c  + b c –
d) a ~ b 
e) a  b ~
a b  –
g) a b ~ 
f)
23
2.
Convert the following postfix form expressions to
infix form:
a) a b + a b – 
b) a b + c 
c) a b c + 
d) a b c + a c d –   b + –
3.
Evaluate the following postfix form expressions
and then convert them to infix form:
a) 4 5 2 + 3  –
b) 2 4 6 – 8 3 –  2 + –
24
4. Evaluate the following prefix form expressions and
then convert them to infix form:
a) – + 4 – 5 ~ 2 +  3 4 6
b) – + 2  – 3 8 – 6 4 2
5. Convert the quadratic formula shown below to
postfix form.
 b  b 2  4ac
x
2a
6. Translate each of the following expressions from
postfix form to prefix form:
a)
b)
c)
d)
a
a
a
a
b
b
!
b
+ c 
c + 
b ! / c d – a ! – 
< not c d  e < or
25
7. Evaluate the following prefix expressions. Hence,
translate them into postfix form:
a) / + 2 4 ! 4
b) / + ! 3 9 3
c) and < 3 4 or not = + 2 5 7 > 3 0
8. Translate each of the following expressions from
infix form into postfix and then by using stack
diagrams evaluate the postfix expressions:
a) 5 * ((-3 – 2) * (4 – 6) + 3 * 2)
b) -3 + (5 + 2) * 8 + 6 – ((4 – 2 * 3) * (-2 – 3) – 9)
c) 9 + 5 * ((3 + 2) – 8 * (1 – 3) * (-3 – 6)) + 2 * 3
d) 1 – (3 – (-1 + 2 * (6 + 7 * 2)))
26
Postfix Evaluation
enum Error_code {fail,success};
typedef Value Stack_entry;
enum Token_type {operand,unaryop,binaryop,invalid};
class Expression {
public:
Error_code evaluate_postfix(Value &result);
bool get_next_token(Token &result); // false if end of expression
// Other methods
Single operator
private:
or operand
// Data members to store an expression
};
Value do_unary(const Token &operator, const Value &operand);
Value do_binary(const Token &operator,
const Value &operand1, const Value &operand2);
Token_type Token::kind();
27
Error_code Expression::evaluate_postfix(Value &result) {
Token t;
Stack operands;
Value x,y;
if (!get_next_token(t)) return fail;
do {
switch(t.kind()) {
case unaryop:
if (operands.empty()) return fail;
operands.top(x);
operands.pop();
operands.push(do_unary(t,x)); break;
case binaryop:
if (operands.empty()) return fail;
operands.top(x);
operands.pop();
if (operands.empty()) return fail;
operands.top(y);
operands.pop();
operands.push(do_binary(t,x,y)); break;
case operand:
operands.push(get_value(t)); break;
default: return fail;
} while (get_next_token(t));
if (operands.empty()) return fail;
operands.top(result);
operands.pop();
if (!operands.empty()) return fail;
return success;
}
28