PUSH “MATT” MATT FRONTBACK PUSH “ANDREW” MATT FRONT ANDREW BACK.
-
Upload
blaise-newton -
Category
Documents
-
view
231 -
download
1
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))