PUSH “MATT” MATT FRONTBACK PUSH “ANDREW” MATT FRONT ANDREW BACK.

Post on 28-Dec-2015

231 views 1 download

Tags:

Transcript of PUSH “MATT” MATT FRONTBACK PUSH “ANDREW” MATT FRONT ANDREW BACK.

CHAPTER 7

QUEUES AND STACKS

A QUEUE IS A CONTAINER IN WHICH:

. INSERTIONS ARE MADE ONLY AT THE BACK;

. DELETIONS, RETRIEVALS, ANDMODIFICATIONS ARE MADE ONLYAT THE FRONT.

PUSH (ALSO CALLED ENQUEUE) -- TOINSERT AN ITEM AT THE BACK

POP (ALSO CALLED DEQUEUE) -- TODELETE THE FRONT ITEM

IN A QUEUE, THE FIRST ITEM

INSERTED WILL BE THE FIRST ITEM

DELETED: FIFO (FIRST-IN, FIRST-OUT)

PUSH “MATT”

MATT

FRONT BACK

PUSH “ANDREW”

MATT

FRONT

ANDREW

BACK

PUSH “SAMIRA”

SAM IRAMATT

FRONT

ANDREW

BACK

POP

SAM IRA

FRONT

ANDREW

BACK

THE queue CLASS IS TEMPLATED:template <class T, class Container = deque<T> >

T IS THE TEMPLATE PARAMETER

FOR THE ITEM TYPE. Container IS THE

TEMPLATE PARAMETER FOR THE

CLASS THAT WILL HOLD THE ITEMS,

WITH THE deque CLASS THE DEFAULT.

METHOD INTERFACES

FOR THE

queue CLASS

1. // Precondition: this queue object has been initialized// with a copy of this Container object.explicit queue (const Container& = Container( ));

HERE ARE EQUIVALENT EXAMPLES

FOR A QUEUE OF ITEMS OF TYPE Plane;THE ITEMS ARE STORED IN A DEQUE:

queue<Plane> runWay;queue<Plane, deque<Plane> > runWay;queue<Plane> runWay (deque<Plane>( ));queue<Plane, <deque<Plane> > runWay (deque<Plane>( ));

2. // Poscondition: true has been returned if this queue object // is empty. Otherwise, false has been // returned.

bool empty( ) const;

3. // Postcondition: the number of items in this queue object// has been returned.unsigned size( ) const;

4. // Postcondition: the item x has been inserted at the back of// this queue.void push (const value_type& x); // Container class has

// typedef T value_type

5. // Precondition: this queue is not empty.// Postcondition: a reference to the item at the front of// this queue has been returned.T& front( );

6. // Precondition: this queue is not empty.// Postcondition: the item that had been at the front of// this queue before this call has been// deleted from this queue.void pop( );

THE STANDARD TEMPLATE LIBRARY

ALSO PROVIDES A front METHOD

THAT RETURNS A CONSTANT

REFERENCE AND back METHODS

THAT RETURN A REFERENCE OR

CONSTANT REFERENCE TO THE

BACK ITEM.

THERE ARE NO ITERATORS!

THE ONLY ACCESSIBLE ITEM IS THE

FRONT ITEM.

DETERMINE THE OUTPUT FROM THE FOLLOWING:

queue<int> my_queue;

for (int i = 0; i < 10; i++) my_queue.push (i * i);

while (!my_queue.empty()){ cout << my_queue.front() << endl; my_queue.pop();} // while

THE queue CLASS IS A CONTAINER

ADAPTOR. A CONTAINER ADAPTOR C

CALLS THE METHODS FROM SOME

OTHER CLASS TO DEFINE THE

METHODS IN C.

SPECIFICALLY, THE queue CLASS

ADAPTS ANY CONTAINER CLASS

THAT HAS push_back, pop_front, front,

back, size, AND empty METHODS.

deque? OK

list? OK

vector? NOT OK: NO pop_front METHOD

THE STANDARD C++ REQUIRES THAT

THE DEFINITION OF THE queue

CLASS INCLUDE

protected:Container c;

ALSO, THE METHOD DEFINITIONS

ARE PRESCRIBED. FOR EXAMPLE,

public:void push (const value_type& x) { c.push_back (x)); }

void pop( ) { c.pop_front( ); }

const T& front( ) const { return c.front( ); }

IF EITHER A DEQUE OR LIST IS THE

UNDERLYING CONTAINER,

worstTime(n) IS CONSTANT FOR EACH

METHOD.

EXCEPTION: FOR THE push METHOD,

IF A DEQUE IS THE UNDERLYING

CONTAINER, worstTime(n) IS LINEAR IN

n, AND averageTime(n) IS CONSTANT

(AND amortizedTime(n) IS CONSTANT).

APPLICATION OF QUEUES:

COMPUTER SIMULATION

A SYSTEM IS A COLLECTION OF

INTERACTING PARTS.

A MODEL IS A SIMPLIFICATION OF

A SYSTEM.

THE PURPOSE OF BUILDING A MODEL

IS TO STUDY THE UNDERLYING

SYSTEM.

PHYSICAL MODEL: DIFFERS FROM

THE SYSTEM ONLY IN SCALE OR

INTENSITY.

EXAMPLES: WAR GAMES, PRE-SEASON

MATHEMATICAL MODEL: A SET OF

EQUATIONS, VARIABLES, AND

ASSUMPTIONS

A 500’ D

? 200’

500’ C

B 400’ E

ASSUMPTIONS: ANGLE ADC = ANGLE BCDBEC FORMS A RIGHT TRIANGLEDCE FORMS A STRAIGHT LINELINE SEGMENT AB PARALLEL TO DC

DISTANCE FROM A TO B?

IF IT IS INFEASIBLE TO SOLVE THE

MATH MODEL (THAT IS, THE

EQUATIONS) BY HAND, A PROGRAM

IS DEVELOPED.

COMPUTER SIMULATION: THE

DEVELOPMENT OF COMPUTER

PROGRAMS TO SOLVE MATH MODELS

DEVELOP System Computer Model

VERIFY RUN

Interpretation Output DECIPHER

IF THE INTERPRETATION DOES NOTCORRESPOND TO THE BEHAVIOR OFTHE SYSTEM, CHANGE THE MODEL!

FEEDBACK: A PROCESS IN WHICHTHE FACTORS THAT PRODUCE ARESULT ARE THEMSELVESAFFECTED BY THAT RESULT

HERE, THE MODEL IS AFFECTED BYITS OUTPUT.

QUEUE APPLICATION

A SIMULATED CAR WASH

PROBLEM:

GIVEN THE ARRIVAL TIMES ATSPEEDY’S CAR WASH, CALCULATE THEAVERAGE WAITING TIME PER CAR.

ANALYSIS:

ONE WASH STATION

10 MINUTES FOR EACH CAR TO GET

WASHED

AT ANY TIME, AT MOST 5 CARS

WAITING TO BE WASHED; ANY OTHERS

TURNED AWAY AND NOT COUNTED

AVERAGE WAITING TIME = SUM OF

WAITING TIMES / NUMBER OF CARS

IN A GIVEN MINUTE, A DEPARTURE IS

PROCESSED BEFORE AN ARRIVAL.

IF A CAR ARRIVES WHEN NO CAR IS

BEING WASHED AND NO CAR IS

WAITING, THE CAR IMMEDIATELY

ENTERS THE WASH STATION.

A CAR STOPS WAITING WHEN IT

ENTERS THE WASH STATION.

SENTINEL IS 999.

SYSTEM TEST 1:811111314161620999

TIME EVENT WAITING TIME 8 ARRIVAL11 ARRIVAL11 ARRIVAL13 ARRIVAL14 ARRIVAL16 ARRIVAL16 ARRIVAL (OVERFLOW)

18 DEPARTURE 020 ARRIVAL28 DEPARTURE 738 DEPARTURE 1748 DEPARTURE 2558 DEPARTURE 3468 DEPARTURE 4278 DEPARTURE 48

AVERAGE WAITING TIME

= 173 / 7.0 MINUTES

= 24.7 MINUTES

CAR WASH APPLET

http://www.cs.lafayette.edu/~collinsw/carwash/car.html

EXERCISE:

GIVEN THE FOLLOWING ARRIVAL

TIMES, DETERMINE THE AVERAGE

WAITING TIME:

4, 8, 12, 16, 23, 999 (the sentinel)

DESIGN OF CarWash CLASS

// Postcondition: This CarWash object is empty.CarWash( );

// Postcondition: all of the arrivals and departures have// been processed.void runSimulation( );

// Postcondition: the average waiting time, or an error// message, has been printed.void printResult( );

FIELDS?

FIRST, WE’LL DECIDE WHAT

VARIABLES WILL BE NEEDED, AND

THEN CHOOSE THE FIELDS FROM

THOSE VARIABLES.

queue<Car> carQueue;

EACH ITEM IN carQueue WILL BE OF

TYPE Car. WHAT INFORMATION

ABOUT A CAR DO WE NEED?

IN THE Car CLASS:

// Postcondition: the arrival time of the car just// dequeued has been returned.int getArrivalTime( );

NOTE: WE HAVE A Car CLASS FOR

THE SAKE OF LATER MODIFICATIONS

TO THE PROBLEM. FOR EXAMPLE,

THE COST OF A WASH MIGHT

DEPEND ON THE NUMBER OF AXLES.

TO CALCULATE THE AVERAGE

WAITING TIME:

int numberOfCars, sumOfWaitingTimes;

TO GET THE SUM OF THE WAITINGTIMES:

int waitingTime, // = currentTime – arrivalTimearrivalTime, // of car about to be washedcurrentTime;

THE SIMULATION WILL BE

EVENT-BASED: IS THE NEXT EVENT AN

ARRIVAL OR A DEPARTURE?

int nextArrivalTime,nextDepartureTime; // = 10000 if no car being washed

// (so next event will be an arrival)

A RULE OF THUMB IS THAT A FIELD

SHOULD BE NEEDED IN MOST OF THE

CLASS’S PUBLIC METHODS.

FIELDS:

int currentTime,sumOfWaitingTimes,numberOfCars,nextDepartureTime; // = 10000 if no car being washed

NOTE: carQueue IS NOT A FIELD

BECAUSE IT IS NEEDED ONLY IN THE

runSimulation METHOD.

METHOD DEFINITIONS

CarWash::CarWash(){ currentTime = 0; numberOfCars = 0; sumOfWaitingTimes = 0; nextDepartureTime = INFINITY; // = 10000} // default constructor

void CarWash::runSimulation(){ cin >> nextArrivalTime;

while (nextArrivalTime != 999){

// If the next event is an arrival{

// Process that arrivalcin >> nextArrivalTime;

}else

// Process a departure}

// Wash any cars remaining on carQueue. } // runSimulation

void CarWash::runSimulation(){ const string PROMPT = "\nPlease enter the next arrival time. The sentinel is ";

const int SENTINEL = 999;

queue<Car> carQueue;

int nextArrivalTime;

cout << PROMPT << SENTINEL << endl; cin >> nextArrivalTime;

while (nextArrivalTime != SENTINEL) { if (nextArrivalTime < nextDepartureTime) { processArrival (nextArrivalTime, carQueue); cout << PROMPT << SENTINEL << endl; cin >> nextArrivalTime; } // if else processDeparture (carQueue); } // while SENTINEL not reached

// Wash any cars remaining on the carQueue. while (nextDepartureTime < INFINITY) processDeparture (carQueue);} // runSimulation

// Postcondition: the car that arrived at nextArrivalTime has// either been turned away -- if carQueue// was full before this message was sent --// or has entered this CarWash.void processArrival (int nextArrivalTime, queue<Car>& carQueue){ const string OVERFLOW = "Overflow";

currentTime = nextArrivalTime; if (carQueue.size( ) == MAX_SIZE) cout << OVERFLOW << endl; else { numberOfCars++; if (nextDepartureTime == INFINITY) nextDepartureTime = currentTime + WASH_TIME; else carQueue.push (Car (nextArrivalTime)); } // not an overflow} // method processArrival

// Postcondition: a car has finished getting washed and carQueue,// if non-empty, has been popped.void CarWash::processDeparture (queue<Car>& carQueue){

int waitingTime;

cout << "departure time = " << nextDepartureTime << endl; currentTime = nextDepartureTime; if (!carQueue.empty()) { Car car = carQueue.front(); carQueue.pop(); waitingTime = currentTime - car.getArrivalTime(); sumOfWaitingTimes += waitingTime; nextDepartureTime = currentTime + WASH_TIME; } // carQueue was not empty else nextDepartureTime = INFINITY;} // method processDeparture

void CarWash::printResult( ){ const string NO_CARS_MESSAGE =

"There were no cars in the car wash.";

const string AVERAGE_WAITING_TIME_MESSAGE = "\nThe average waiting time, in minutes, was ";

if (numberOfCars == 0) cout << NO_CARS_MESSAGE << endl; else cout << AVERAGE_WAITING_TIME_MESSAGE << ((double)sumOfWaitingTimes / numberOfCars) << endl;} // method printResult

RANDOMIZING THE ARRIVAL TIMES

IF THE VALUES FOR nextArrivalTime

ARE READ IN, THE RESULTS ARE NOT

GENERALIZABLE. INSTEAD, WE

WILL READ IN

int meanArrivalTime; // the average time between arrivals

THEN WE CALCULATE:

double randomDouble = rand ( ) / double (RAND_MAX + 1);

int timeTillNext = -meanArrivalTime * log (1 - randomDouble) + 0.5;

THEN currentTime IS INCREMENTED BY

timeTillNext.

FOR EXAMPLE, ASSUME THAT

meanArrivalTime IS 3. IF

log (1 – randomDouble) = –0.6 AND

currentTime = 25,

WHEN WILL THE NEXT ARRIVAL

OCCUR?

timeTillNext = -meanArrivalTime * log (1 - randomDouble) +0.5;

= (-3 * -0.6) + 0.5;

= 2.3

SO timeTillNext GETS THE VALUE 2, AND

THE NEXT ARRIVAL WILL OCCUR AT

TIME 25 + 2 = 27 MINUTES.

STACKS

A STACK IS A CONTAINER IN WHICH

IN WHICH THE ONLY ITEM THAT

CAN BE REMOVED, ACCESSED, OR

MODIFIED IS THE ITEM THAT WAS

MOST RECENTLY INSERTED.

THE LAST ITEM INSERTED IS THEFIRST ITEM TO BE REMOVED. LAST-IN, FIRST-OUT (LIFO).

COMPARE WITH A QUEUE: FIRST-IN,FIRST-OUT (FIFO).

TOP – THE MOST RECENTLY INSERTED

ITEM

PUSH - TO INSERT ONTO THE TOP OF A

STACK

POP - TO REMOVE THE TOP ITEM IN A

STACK

START WITH AN EMPTY STACK.

PUSH “CLAYTON”.

TOP CLAYTON

PUSH “ERIC”.

TOP ERIC

CLAYTON

POP.

TOP CLAYTON

THE stack CLASS IS TEMPLATED:

template <class T, class Container = deque<T> >

T IS THE TEMPLATE PARAMETER

FOR THE ITEM TYPE. Container IS THE

TEMPLATE PARAMETER FOR THE

CLASS THAT WILL HOLD THE ITEMS.

METHOD INTERFACES

FOR THE

stack CLASS

1. // Postcondition: This stack object is empty, that is, it// contains no items.explicit stack (const Container& = Container( ));

2. // Postcondition: True has been returned if this stack // object is empty. Otherwise, false has

// been returned.bool empty( );

3. // Postcondition: The number of items in this stack // object has been returned.

unsigned size( );

4. // Postcondition: x has been inserted at the top of// this stack object.void push (const T& x);

5. // Precondition: This stack object is not empty.// Postcondition: A reference to the top item on this// stack object has been returned.

T& top( );

6. // Precondition: This stack object is not empty.// Postcondition: A constant reference to the top item// on this stack object has been// returned.const T& top( ) const;

7. // Precondition: This stack object is not empty.// Postcondition: The item that had been at the top of

// this stack object before this method// was called has been removed.void pop( );

THERE ARE NO ITERATORS!

THE ONLY ACCESSIBLE ITEM IS THE

FRONT ITEM.

DETERMINE THE OUTPUT FROM THE FOLLOWING:

stack<int> my_stack;

for (int i = 0; i < 10; i++) my_stack.push (i * i);

while (!my_stack.empty()){ cout << my_stack.top() << endl; my_stack.pop();} // while

LIKE THE queue CLASS, THE stack

CLASS IS A CONTAINER ADAPTER.

THE UNDERLYING CLASS MUST HAVE

empty, size, push_back, pop_back, AND

back METHODS.

SO THE vector, deque, AND list CLASSES

CAN SERVE AS THE UNDERLYING

CONTAINER CLASS.

NOTE: THE TOP ITEM ON THE

STACK IS AT THE BACK OF THE

UNDERLYING CONTAINER!

HERE IS PART OF THE DEFINITION OF

THE stack CLASS:

template <class T, class Container = deque<T> >class stack{ protected: Container c;

public:

void push (const value_type& x) { c.push_back (x); }}

STACK APPLICATION 1

HOW COMPILERS IMPLEMENT

RECURSION

WHENEVER A FUNCTION IS CALLED,

INFORMATION IS SAVED TO

PREVENT OVERLAYING OF THAT

INFO IN CASE THE METHOD IS

RECURSIVE. THIS INFORMATION IS

COLLECTIVELY REFERRED TO AS AN

ACTIVATION RECORD OR STACK

FRAME.

 

         

         

         

EACH ACTIVATION RECORD CONTAINS:

1. A VARIABLE THAT CONTAINS THE RETURN ADDRESSIN THE CALLING METHOD;

2. FOR EACH VALUE FORMAL PARAMETER, A VARIABLE THAT CONTAINS A COPY OF THE ARGUMENT;

3. FOR EACH REFERENCE FORMAL PARAMETER, A VARIABLE THAT CONTAINS THE ADDRESS OF THE ARGUMENT;

4. FOR EACH VARIABLE DEFINED IN THE METHOD’S BLOCK, A VARIABLE THAT CONTAINS A COPY OF THATDEFINED VARIABLE. 

      

       

THERE IS A RUN-TIME STACK TO

HANDLE THESE ACTIVATION

RECORDS.

PUSH: WHEN FUNCTION IS CALLED

POP: WHEN EXECUTION OF FUNCTION

IS COMPLETED       

AN ACTIVATION RECORD IS SIMILAR

TO AN EXECUTION FRAME, EXCEPT

THAT AN ACTIVATION RECORD HAS

VARIABLES ONLY, NO CODE.

YOU CAN REPLACE RECURSION WITH

ITERATION BY CREATING YOUR OWN

STACK.

RECALL FROM CHAPTER 4: DECIMALTO BINARY:

// Precondition: n >= 0.// Postcondition: The binary equivalent of n has been// printed. The worstTime(n) is O(log n).void writeBinary (int n){ if (n == 0 || n == 1) cout << n; else { writeBinary (n / 2); cout << n % 2; } // else} // writeBinary

HERE IS A STACK-BASED VERSION:

void writeBinary (int n){ stack<int> myStack; myStack.push (n); while (n > 1)

{ n = n / 2; myStack.push (n); } // pushing while (!myStack.empty())

{ n = myStack.top(); myStack.pop(); cout << (n % 2); } // popping cout << endl << endl;} // method writeBinary

EXERCISE: TRACE THE EXECUTION

OF THE ABOVE FUNCTION AFTER

AN INITIAL CALL OF

writeBinary (20);

SHOW THE CONTENTS OF myStack.

STACK APPLICATION 2

CONVERTING FROM

INFIX TO POSTFIX

IN INFIX NOTATION, AN OPERATOR IS

PLACED BETWEEN ITS OPERANDS.

a + b

c – d + (e * f – g * h) / i

OLD COMPILERS:

INFIX MACHINE LANGUAGE

THIS GETS MESSY BECAUSE OF PARENTHESES.

NEWER COMPILERS:

INFIX POSTFIX MACHINE LANGUAGE

IN POSTFIX NOTATION, AN OPERATOR IS PLACED IMMEDIATELY AFTER ITS OPERANDS.

INFIX

POSTFIX

a + b

ab+

a + b * c

abc*+

a * b + c

ab*c+

(a + b) * c

ab+c*

PARENTHESES ARE NOT NEEDED,

AND NOT USED, IN POSTFIX.

LET’S CONVERT AN INFIX STRING TO

A POSTFIX STRING. 

   x – y * z   

POSTFIX PRESERVES THE ORDER OF

OPERANDS, SO AN OPERAND CAN BE

APPENDED TO POSTFIX AS SOON AS

THAT OPERAND IS ENCOUNTERED IN

INFIX.

INFIX POSTFIX

x – y * z x

INFIX POSTFIX

x – y * z x

THE OPERANDS FOR ‘-’ ARE NOT YET

IN POSTFIX, SO ‘-’ MUST BE

TEMPORARILY SAVED SOMEWHERE.

INFIX POSTFIX

x – y * z xy

INFIX POSTFIX

x – y * z xy

THE OPERANDS FOR ‘*’ ARE NOT YET

IN POSTFIX, SO ‘*’ MUST BE

TEMPORARILY SAVED SOMEWHERE,

AND RESTORED BEFORE ‘-’.

INFIX POSTFIX

x – y * z xyz

INFIX POSTFIX

x – y * z xyz* –

SUPPOSE, INSTEAD, WE STARTED WITH

x*y-z. AFTER MOVING ‘x’ TO POSTFIX,

‘*’ IS TEMPORARILY SAVED, AND THEN

‘y’ IS APPENDED TO POSTFIX. WHAT

HAPPENS WHEN ‘-’ IS ACCESSED?

INFIX POSTFIX

x * y – z xy

THE ‘*’ MUST BE MOVED TO POSTFIX

NOW, BECAUSE BOTH OF THE

OPERANDS FOR ‘*’ ARE ON POSTFIX.

THEN THE ‘-’ MUST BE SAVED

TEMPORARILY. AFTER ‘z’ IS MOVED

TO POSTFIX, ‘-’ IS MOVED TO

POSTFIX, AND WE ARE DONE.

INFIX POSTFIXx * y – z xy*z–

THE TEMPORARY STORAGE FACILITY

IS A STACK.

HERE IS THE STRATEGY FOR

MAINTAINING THE STACK:

FOR EACH OPERATOR IN INFIX: LOOP UNTIL OPERATOR PUSHED: IF OPERATOR STACK IS EMPTY,

PUSH ELSE IF INFIX OPERATOR HAS GREATER PRECEDENCE

THAN TOP OPERATORON STACK,

PUSH ELSE

POP AND APPEND TO POSTFIX

INFIX GREATER, PUSH

CONVERT FROM INFIX TO POSTFIX:

INFIX POSTFIX

a + b * c / d - e

INFIX POSTFIX

a + b * c / d – e abc*d/+e –

-

/

*

+

OPERATOR STACK

WHAT ABOUT PARENTHESES?

LEFT PARENTHESIS: PUSH, BUT

WITH LOWEST PRECEDENCE.

RIGHT PARENTHESIS:KEEP POPPING

AND APPENDING TO POSTFIX UNTIL

‘(‘ POPPED; PITCH ‘(‘ AND PROCEED.

CONVERT TO POSTFIX:

x * (y + z)

INFIX POSTFIXx * (y + z) xyz+*

+ ( *

OPERATOR STACK

INFIX POSTFIXx * (y + z – (a / b + c) * d) / e

OPERATOR STACK

TO DECIDE WHAT ACTION TO TAKE IN

CONVERTING FROM INFIX TO

POSTFIX, ALL WE NEED TO KNOW IS

THE CURRENT CHARACTER IN INFIX

AND THE TOP CHARACTER ON

OPERATOR STACK.

THE FOLLOWING TRANSITION

MATRIX SPECIFIES THE TRANSITION

FROM INFIX NOTATION TO POSTFIX

NOTATION:

TOP CHARACTER ON STACK ( +,- *,/ emptyI

N identifierF

I )X ( +,-C

H *,/A

R empty

APPEND APPEND APPEND APPEND TO TO TO TOPOSTFIX POSTFIX POSTFIX POSTFIX

POP; POP TO POP TO ERRORPITCH ‘(‘ POSTFIX POSTFIXPUSH PUSH PUSH PUSH

PUSH POP TO POP TO PUSH POSTFIX POSTFIX

PUSH PUSH POP TO PUSH POSTFIXERROR POP TO POP TO DONE POSTFIX POSTFIX

TOKENS

A TOKEN IS THE SMALLEST

MEANINGFUL UNIT IN A PROGRAM.

EACH TOKEN HAS TWO PARTS:

A GENERIC PART, FOR THE

CATEGORY OF THE TOKEN;

A SPECIFIC PART, TO ACCESS

THE CHARACTERS IN THE TOKEN.

FOR EXAMPLE:

// index 35 in symbol table

add_op +, -

identifier 35

INFIX-TO-POSTFIX APPLET

http://www.cs.lafayette.edu/~collinsw/infix/infix.html

IN PREFIX NOTATION, AN OPERATOR

IMMEDIATELY PRECEDES ITS

OPERANDS.

INFIX PREFIXa + b +ab

a * (b + c) *a+bc

a * b + c +*abc

IN PREFIX NOTATION, AS IN POSTFIX,

THERE ARE NO PARENTHESES.

TWO STACKS ARE USED:

OPERATOR STACK: SAME RULES AS

FOR POSTFIX STACK

OPERAND STACK: TO HOLD THE

OPERANDS

WHENEVER opt IS POPPED FROM

OPERATOR STACK, opd1 AND THEN

opd2 ARE POPPED FROM OPERAND

STACK. THE STRING opt + opd2 + opd1

IS PUSHED ONTO OPERAND STACK.

NOTE: opd2 WAS PUSHED BEFORE opd1.

CONVERT FROM INFIX TO PREFIX:

INFIXa + (b * c – d) / e

INFIX PREFIXa + (b * c – d) / e +a/– *bcde

+a/– *bcde /– *bcde e –*bcd d / *bc – c * b (

a + OPERAND OPERATOR

STACK STACK

EXERCISE: CONVERT TO PREFIX

a – b + c * (d / e – (f + g))