stacks21 stacks ii adventures in notation. stacks22 the trouble with infix... rules for expression...

34
stacks2 1 Stacks II Stacks II Adventures in Notation

Upload: ira-buck-turner

Post on 17-Dec-2015

227 views

Category:

Documents


0 download

TRANSCRIPT

stacks2 1

Stacks IIStacks II

Adventures in Notation

stacks2 2

The trouble with infix ...The trouble with infix ...

• Rules for expression evaluation seem simple -- evaluate expression left to right, results of each sub-expression becoming operands to larger expression -- but …

• All operators are not created equal -- multiplication & division take precedence over addition & subtraction ...

stacks2 3

The trouble with infix ...The trouble with infix ...

• So it isn’t really all that simple -- we must first scan for higher-precedence operations, and evaluate these first -- and that’s not so easy to program -- so …

• In the calculator program, we rely on parentheses to tell us which operations to perform when -- hence the need for fully-parenthesized expression

stacks2 4

Alternatives to infix -- prefixAlternatives to infix -- prefix

• Prefix notation, a.k.a. Polish notation

• Operator precedes operands– infix expression: A + B– prefix expression: +AB

• Parentheses become unnecessary– infix expression: (A + B) * C– prefix expression: * + A B C

stacks2 5

Converting from infix to prefixConverting from infix to prefix

• Write out operands in original order

• Place operators in front of their operands

• If there’s a compound expression, the prefix expression may have two or more operators in a row

• If parentheses are not present, pay attention to precedence

stacks2 6

A + B + C >>>>>> + + A B C

A - B + C >>>>>> + - A B C

A + (B - C) >>>>> + A - B C

A * ((B + C) - D) / E >>> / * A - + B C D E

A + B * C / D >>>> + A / * B C D

A * B + C - D / E >>> - + * A B C / D E

Conversion examplesConversion examples

stacks2 7

Prefix evaluationPrefix evaluation

• scan left to right until we find the first operator immediately followed by pair of operands

• evaluate expression, and replace the “used” operator & operands with the result

• continue until a single value remains

stacks2 8

Prefix ExamplePrefix Example

+ * / 4 2 3 9 // original expression

+ * 2 3 9 // 4/2 evaluated

+ 6 9 // 2*3 evaluated

15 // 6+9 evaluated

stacks2 9

Another exampleAnother example

* - + 4 3 5 / + 2 4 3 // original expression

* - 7 5 / + 2 4 3 // 4+3 evaluated

* 2 / + 2 4 3 // 7-5 evaluated

* 2 / 6 3 // 2+4 evaluated

* 2 2 // 6/3 evaluated

4 // 2*2 evaluated

stacks2 10

Prefix summaryPrefix summary

• Operands (but often not operators) same order as infix

• Expression designated unambiguously without parentheses

• Improvement on infix, but still not quite as simple to evaluate as one might wish -- have to deal with exceptions

stacks2 11

Alternative II: PostfixAlternative II: Postfix

• Postfix is also known as reverse Polish notation -- widely used in HP calculators

• In postfix notation, operators appear after the operands they operate on

• As with prefix, operand order is maintained, and parentheses are not needed

• Postfix expression is notnot merely a reverse of the equivalent prefix expression

stacks2 12

Postfix expression examplesPostfix expression examples• Simple expression:

– Original Expression: A + B– Postfix Equivalent: A B +

• Compound expression with parentheses:– original: (A + B) * (C - D)– postfix: A B + C D - *

• Compound expression without parentheses:– original: A + B * C - D– postfix: A B C * + D -

stacks2 13

Postfix expression evaluationPostfix expression evaluation

• Read expression left to right

• When an operand is encountered, save it & move on

• When an operator is encountered, evaluate expression, using operator & last 2 operands saved, saving the result

• When entire expression has been read, there should be one value left -- final result

stacks2 14

Postfix evaluation using stackPostfix evaluation using stack

• Postfix evaluation can easily be accomplished using a stack to keep track of operands

• As operands are encountered or created (through evaluation) they are pushed on stack

• When operator is encountered, pop two operands, evaluate, push result

stacks2 15

Postfix calculator codePostfix calculator code

int main( )

{

double answer;

cout << "Type a postfix arithmetic expression:" << endl;

answer = read_and_evaluate(cin);

cout << "That evaluates to " << answer << endl;

return EXIT_SUCCESS;

}

stacks2 16

Postfix calculator codePostfix calculator code

double read_and_evaluate(istream& ins)

{

Stack<double> numstack;

double number;

char symbol;

...

stacks2 17

Postfix calculator codePostfix calculator code

while (!ins.eof( ) && ins.peek( ) != '\n')

{

if (isdigit(ins.peek( )) || (ins.peek( ) == ‘.’))

{

ins >> number;

numstack.push(number);

} …

stacks2 18

Postfix calculator codePostfix calculator code

else if (strchr("+-*/", ins.peek( )) != NULL)

{

ins >> symbol;

evaluate(numstack, symbol);

}

else

cin.ignore( );

} // end of while loop

return numstack.pop( );

}

stacks2 19

Postfix calculator codePostfix calculator code

void evaluate(Stack<double>& numbers, char op)

{

double operand1, operand2;

operand2 = numbers.pop( );

operand1 = numbers.pop( );

...

stacks2 20

Postfix calculator codePostfix calculator code

switch (op)

{

case '+':

numbers.push(operand1 + operand2);

break;

case '-':

numbers.push(operand1 - operand2);

break;

...

stacks2 21

Postfix calculator codePostfix calculator code

case '*':

numbers.push(operand1 * operand2);

break;

case '/':

numbers.push(operand1 / operand2);

break;

} // end switch statement

} // end function

stacks2 22

Translating infix to postfixTranslating infix to postfix

• Postfix expression evaluation is easiest type to program

• Next task is to take an infix expression and translate it into postfix for evaluation

• Some basic assumptions:– all operations are binary (no unary negative)– expressions are fully parenthesized

stacks2 23

Translating infix to postfixTranslating infix to postfix

• General method:– move each operator to the right of its

corresponding right parenthesis– eliminate parentheses

• Example:(((A + B) * C) - (E * (F + G)))

(((A B) + C) * (E (F G) +) * ) -

A B+ C * E F G + * -

stacks2 24

Pseudocode for translation Pseudocode for translation programprogram

Do {

if (left parenthesis) read & push

else if (operand) read & write to file

else if (operator) read & push

else if (right parenthesis)

read & discard

pop operand & write to file

pop & discard left parenthesis

} while (expression to read)

stacks2 25

Translation program codeTranslation program code

void main( )

{

Stack<char> opstack;

char ch;

double num;

ofstream outfile;

...

stacks2 26

Translation program codeTranslation program code

outfile.open(“EXPRESS.TXT”);

cout << “Enter a fully-parenthesized infix “;

cout << “expression below: “ << endl;

while (cin && cin.peek != ‘\n’)

{

...

stacks2 27

Translation program codeTranslation program code

// check for operand -- write to file if found

if (isdigit (cin.peek( ) || cin.peek( ) == ‘.’)

{

cin >> num;

outfile << num;

}

stacks2 28

Translation program codeTranslation program code

// check for operator or left parenthesis;

// if found, push on stack

else if (strchr( “+-*/(“, cin.peek( ))!=NULL)

{

cin >> ch;

opstack.push(ch);

}

stacks2 29

Translation program codeTranslation program code

// check for right parenthesis -- if found,

// pop stack & send operator to file

else if (cin.peek( ) == ‘)’)

{

cin.ignore( ); // discard right paren

outfile << opstack.pop( );

opstack.pop( ); // discard left paren

}

stacks2 30

Translation program codeTranslation program code

else // it’s some other character - who cares?

cin.ignore( );

} // end of while loop

cin.ignore( ); // discard newline character

return;

}

stacks2 31

OK -- but what if expression OK -- but what if expression isn’tisn’t fully parenthesized?fully parenthesized?

• We have to fall back on the rules for expression evaluation we know & love– do expression in parentheses first– do other operations in order of precedence -- in

case of tie, leftmost sub-expression wins

• Example: A - ( B + C) * D - E

• order: 3 1 2 4

• Postfix: A B C + D * - E -

stacks2 32

Algorithm for expression Algorithm for expression conversionconversion

Do

if (left parenthesis) read & push

else if (operand) read & write to file

else if (arithmetic operator)

// continued on next slide

...

stacks2 33

Conversion algorithm continuedConversion algorithm continued

while (stack not empty && stack.peek( ) != ‘(‘ &&

op precedence lower than stack.peek( ))

pop stack & write to file

read op

push op

else // character should be ‘)’

// next slide ...

stacks2 34

Conversion algorithm continuedConversion algorithm continuedread & discard right paren

do

pop stack & write to file

while (stack.peek( ) != ‘(‘)

pop & discard left paren

while (expression to read) // ends outer loop

while (stack not empty)

pop & write to file