Chapter 04 Stacks

Embed Size (px)

Citation preview

  • 7/30/2019 Chapter 04 Stacks

    1/43

    Chapter 4: Stacks

    Introduction:

    Consider the problems on pp. 170-1

    (1) Model the discard pile in a card

    game

    (2) Model a railroad switching

    yard

    (3) Parentheses checker(4) Calculate and display base-

    two representation

    of base-ten numbers; e.g.,

    2610 = ???????2

    Siding

    Main Track

  • 7/30/2019 Chapter 04 Stacks

    2/43

    In the last problem:Remainders are generated in right-to-left order. We need to

    "stack" them up, then print them out from top to bottom.

    In these problems we need a

    "last-discarded-first-removed,"

    "last-pushed-onto-first-removed,"

    "last-stored-first-removed, ""last-generated-first-displayed"

    structured data type.

    In summary ... a LIFO (Last-In-First-Out) structure.

    LIFO

  • 7/30/2019 Chapter 04 Stacks

    3/43

    Stack as an ADT

    A stack is anorderedcollection of data items in whichaccess is

    possible only at one end(called thetop of the stack).

    Basic operations:

    1. Construct a stack (usually empty)

    2. Check if stackis empty

    3. Push: Add an element at the top of the stack

    4. Top: Retrievethetop element of the stack

    5. Pop: Removethetop element of the stack

    Terminology is from spring-loaded

    stack of plates in a cafeteria:Adding a plate pushes those below it

    down in the stackRemoving a plate pops those below it

    up one position.

  • 7/30/2019 Chapter 04 Stacks

    4/43

    Example use of StackBASE-CONVERSION ALGORITHM

    (See p. 171-2)

    /* This algorithm displays the base-2 representation

    of a base-10 number.

    Receive: a positive integer number

    Output: the base-two representation ofnumber.

    ---------------------------------------------------------------*/

    1. Create an empty stack to hold the remainders.

    2. While number 0:

    a. Calculate the remainderthat results when

    numberis divided by 2.

    b. Push remainderonto the stack of remainders.

    c. Replace numberby the integer quotient of

    numberdivided by 2.

  • 7/30/2019 Chapter 04 Stacks

    5/43

    3. While the stack of remainders is notempty:

    a. Retrieve and remove the remainder

    from the top of the stack of

    remainders.

    b. Display remainder.

    Example (contd.)

  • 7/30/2019 Chapter 04 Stacks

    6/43

    /* Program that uses a stack to convert the base-ten

    * representation of a positive integer to base two.** Input: A positive integer* Output: Base-two representation of the number***************************************************/

    #include "Stack.h" // our own -- for STL version#include using namespace std;

    int main()

    {unsigned number, // the number to be converted

    remainder; // remainder when number is// divided by 2

    Stack stackOfRemainders; // stack of remainders

    char response; // user response

    Base10 to Base2 Conversion

  • 7/30/2019 Chapter 04 Stacks

    7/43

    do{cout > number;

    while (number != 0){remainder = number % 2;stackOfRemainders.push(remainder);number /= 2;

    }cout

  • 7/30/2019 Chapter 04 Stacks

    8/43

    Building a Stack ClassTwo steps:1. Design the class; and

    2. Implement the class.

    Identify the operations needed to manipulate "real-world" objects

    being modeled by class.

    Operations are described:

    Independent of class implementation.

    In a manner independent of any specific representation of object

    (because we have no idea what data members will be available).

    1. Designing a Stack Class

  • 7/30/2019 Chapter 04 Stacks

    9/43

    //***** Constructors *****

    Construction: Initializes an empty stack

    //***** Mutators *****

    Push operation: Modifies a stack by adding a value to top of

    stackPop operation: Modifies a stack by removing the top value

    of the stack

    //***** Accessors *****Top operation: Retrieves the value at the top of the stack

    Empty operation: Determines if stack contains any values

    To help with debugging, add early on:

    Output: Displays all the elements stored in the stack.

    Stack Operations:

  • 7/30/2019 Chapter 04 Stacks

    10/43

    2. Implementing a Stack ClassDefine data members: consider storage structure(s)

    Attempt #1: Use an array with the top of the stack at position 0.e.g., Push 75, Push 89, Push 64, Pop

    + features: This models the operation of the stack of plates.

    features: Not efficient to shift the array elements up and down in the array.

    0123

    4

    0123

    4

    75

    Push 75

    0123

    4

    89

    Push 89

    750123

    4

    89

    Push 64

    75

    64 0123

    4

    89

    Pop

    75

    I l ti Cl

  • 7/30/2019 Chapter 04 Stacks

    11/43

    Implementing Stack Class

    Refined

    Keep thebottom of stack at position 0. Maintain a "pointer"myTop to the top

    of the stack.

    Instead of modeling a stack of plates, model a stack of books (or a discard pile in a

    card game.)

    7589

    43210

    Push 75 Push 89

    7589

    Push 64

    75

    64

    Pop43210

    43210

    43210

    43210

    8975

    64

    myTopmyTop

    myTopmyTop

    myTop

    myTop = -1 myTop = 0 myTop = 1 myTop = 2 myTop = 1

    Note: No moving of array elements.

    Note: Wedon't clear

    this.

  • 7/30/2019 Chapter 04 Stacks

    12/43

    Provide:

    An array data member to hold the stack elements. An integer data member to indicate the top of the stack.

    Problems: We need an array declaration of the formArrayElementTypemyArray[ARRAYCAPACITY];

    What type should be used?Solution (for now): Use the typedef mechanism:

    typedef int StackElement;// put this before the class declaration

    What about the capacity?const int STACK_CAPACITY = 128;// put this before the class declaration

    Now we can declare the array data member in the private section:StackElement myArray[STACK_CAPACITY];

    Stack's Data Members

  • 7/30/2019 Chapter 04 Stacks

    13/43

    1. typedef makes StackElement a synonym for int

    2. Want a stack of reals, or characters, or . . . ? Change thetypedeftypedef double StackElementType;

    or

    typedef char StackElementType;

    or . . .When class library is recompiled, array elements will be double or char or . . .

    3. An alternative to using and changing a typedef: Atemplateto build a Stack class is written whose element type is left unspecified.

    The element type is passed as a specialkind ofparameter at

    compile time.

    This is the approach used in the Standard Template Library (STL)and in

    most of the other C++ libraries.

    Notes

  • 7/30/2019 Chapter 04 Stacks

    14/43

    4. The typedef and declaration ofSTACK_CAPACITY outside the class

    declaration makes them:

    easy to find when they need changing

    accessible throughout the class and in any file that #includes Stack.h

    without qualification

    If we put typedef ofStackElement and declaration of the constant

    STACK_CAPACITY in public section of the class declaration, they can be

    accessed outside the class, but require qualification:

    Stack::StackElementStack::STACK_CAPACITY (for class)s.STACK_CAPACITY (for object)

    5. If we were to make STACK_CAPACITY a data member, we would probablymake it a static data member:

    static const int STACK_CAPACITY = 128;

    This makes it a property of the class usable by all class objects, but they

    do not have their own copies ofSTACK_CAPACITY.

  • 7/30/2019 Chapter 04 Stacks

    15/43

    /* Stack.h provides a Stack class.* Basic operations:* Constructor: Constructs an empty stack* empty: Checks if a stack is empty* push: Modifies a stack by adding a value at the top* top: Accesses the top stack value; leaves stack* unchanged

    * pop: Modifies a stack by removing the value at the* top* display: Displays all the stack elements* Class Invariant:* 1. The stack elements (if any) are stored in positions* 0, 1, . . ., myTop of myArray.

    * 2. -1

  • 7/30/2019 Chapter 04 Stacks

    16/43

    #ifndef __STACK_H

    #define __STACK_H

    const int STACK_CAPACITY = 128;typedef int StackElement;

    class Stack

    {/***** Function Members *****/

    public:. . .

    /***** Data Members *****/

    private:StackElement myArray[STACK_CAPACITY];int myTop;

    }; // end of class declaration. . .

    #endif

    Stack.h (contd.)

  • 7/30/2019 Chapter 04 Stacks

    17/43

    Stack's Function MembersConstructor:

    class Stack{

    public:

    /*--- Constructor ---Precondition: A stack has been declared.Postcondition: Stack has been constructed

    as an empty stack.*/Stack();

    ...} // end of class declaration

    Simple

    enough to

    inline?

    inline Stack::Stack() { myTop = -1; }

    Yes

    NOTE THE

    DOCUMENTATION

  • 7/30/2019 Chapter 04 Stacks

    18/43

    A declaration

    Stack s;

    will construct s as follows:

    s 0 1 2 3 4 . . . 127

    myArray ? ? ? ? ? . . . ?

    myTop -1

    A sample declaration

  • 7/30/2019 Chapter 04 Stacks

    19/43

    Receives Stack containing it as a function member (perhaps implicitly)

    Returns: True if stack is empty, false otherwise.

    Member function? Yes

    Yes

    YesConst function? (Shouldn't alter data members)?

    Simple enough to inline?

    class Stack{

    public:. . .

    /* --- Is the Stack empty? ---* Returns: true if the Stack containing this* function is empty and false otherwise

    ***************************************************/bool empty() const;

    . . .};// end of class declaration

    inline bool Stack::empty() const

    { return (myTop == -1); }

    Empty Member Function

  • 7/30/2019 Chapter 04 Stacks

    20/43

    #include #include

    #include "Stack.h"using namespace std;int main(){

    Stack s;cout

  • 7/30/2019 Chapter 04 Stacks

    21/43

    Receives Stack containing it as a function member (perhaps implicitly)

    Value to be added to stack

    Returns: Modified stack (perhaps implicitly)

    Member function? YesProbably notNoConst function? Simple enough to inline?

    Add to class declaration:

    /* --- Add a value to the stack ---*

    * Receive: A value to be added to a Stack* Postcondition: Value is added at top of stack* provided there's space* Output: "Stack full" message if no space

    *************************************************/

    void push(const StackElement & value);

    Push member function

  • 7/30/2019 Chapter 04 Stacks

    22/43

    void Stack::push(const StackElement & value){

    if (myTop < STACK_CAPACITY - 1){ //Preserve stack invariant++myTop;

    myArray[myTop] = value;} // or simply,myArray[++myTop] = value;

    elsecerr

  • 7/30/2019 Chapter 04 Stacks

    23/43

    Add at bottom of driver:

    for (int i = 1; i

  • 7/30/2019 Chapter 04 Stacks

    24/43

    Receives: Stack containing it as a function member (perhaps implicitly)

    an ostream

    Output: Contents of Stack, from the top down.

    Member function? Yes YesYesConst function? Simple enough to inline?

    Add to class declaration:

    /* --- Display values stored in the stack ---** Receive: The ostream out* Output: Stack's contents, from top down, to out***************************************************/void display(ostream & out) const;

    Add toStack.hinline voidStack::display(ostream & out) const{for (int i = myTop; i >= 0; i--)out

  • 7/30/2019 Chapter 04 Stacks

    25/43

    Modify driver:/*for (int i = 1; i

  • 7/30/2019 Chapter 04 Stacks

    26/43

    Add to class declaration:

    /* --- Return value at top of the stack ---* Return: value at the top of nonempty Stack* Output: "Stack empty" message if stack empty***************************************************/StackElement top() const;

    Receives: Stack containing it as a function member (perhaps implicitly)

    Returns: Value at the top of the stack

    Output: Error message if stack is empty

    Member function? Yes

    No?YesConst function?

    Simple enough to inline?

    Top Member Function

  • 7/30/2019 Chapter 04 Stacks

    27/43

    StackElement Stack::top() const

    { if (myTop >= 0) // or if (!empty())return (myArray[myTop]);

    else{

    cerr

  • 7/30/2019 Chapter 04 Stacks

    28/43

    Receives Stack containing it as a function member (perhaps implicitly)Returns: Stack with top element removed (perhaps implicitly)

    Output: Error message if stack is empty.

    Member function? Yes YesNoConst function? Simple enough to inline?

    class Stack

    . . ./* --- Remove value at top of the stack ---* Postcondition: Top value of stack (if any) has* been removed.* Output: "Stack-empty" message if stack is empty.**************************************************/void pop();

    . . .}; // end of class declaration

    Pop Member Function

    Pop (contd )

  • 7/30/2019 Chapter 04 Stacks

    29/43

    inline void Stack::pop(){

    if (myTop >= 0) // Preserve stack invariant

    myTop--;elsecerr

  • 7/30/2019 Chapter 04 Stacks

    30/43

    Application of Stacks: Run-timeStack

    Whenever a function begins execution (i.e., is activated), an

    activation record(or stack frame) is created to store the

    current environmentfor that function. Its contents include:

    parameterscaller's state information (saved)

    (e.g., contents of registers, return address)

    local variables

    temporary storage

    What kind of data structure should be used to store these so

    that they can be recovered and the system reset when the

    function resumes execution?

  • 7/30/2019 Chapter 04 Stacks

    31/43

    Problem: FunctionA can call FunctionB

    FunctionB can call FunctionC

    . . .When a function calls another function, it interrupts its own

    execution and needs to be able to resume its execution in the

    same state it was in when it was interrupted.

    When FunctionCfinishes, control should return to FunctionB.When FunctionB finishes, control should return to FunctionA.

    So, the order of returns from a function is the reverse of

    function invocations; that is, LIFO behavior.

    Use a stack to store the activation records. Since it is manipulatedat run-time, it is called the run-time stack.

    Exampleon slide 33

  • 7/30/2019 Chapter 04 Stacks

    32/43

    What happens when a function is called?1. Push a copy of its activation record onto the run-time stack

    2. Copy its arguments into the parameter spaces

    3. Transfer control to the address of the function's body

    The top activation record in the run-time stack isalways that of

    the function currently executing.

    What happens when a function terminates?

    1. Pop activation record of terminated function from therun-time stack

    2. Use new top activation record to restore the

    environment of the interrupted function and resume

    execution of the interrupted function.

    Run-time Stack Process

    E l

  • 7/30/2019 Chapter 04 Stacks

    33/43

    Trace run-time stack for the

    following:. . .int main(){ . . .f2(...);f3(...);

    }

    void f1(...) {. . .}void f2(...){... f1(...); ...}void f3(...){... f2(...); ...}

    Examplesint factorial(int n){if (n < 2)return 1;

    elsereturn n * factorial(n-1);

    }

    What happens to the run-time stack when the

    following statement executes?

    int answer = factorial(4);

    This pushing and popping of the run-time stack is the real

    overhead associated with function calls that inlining avoids

    by replacing the function call with the body of the function.

  • 7/30/2019 Chapter 04 Stacks

    34/43

    Application of Stacks: RPN

    1. What is RPN (Reverse Polish Notation)?A notation for arithmetic expressions in which operators are written

    after the operands. Expressions can be written without using

    parentheses.

    Developed by Polish logician, Jan Lukasiewics, in 1950's

    Infix notation: operators written between the operandsPostfix " (RPN): operators written after the operandsPrefix " : operators written before the operands

    Examples:

    INFIX RPN (POSTFIX) PREFIX

    A + BA * B + CA * (B + C)A - (B - (C - D))A - B - C - D

    A B + + A BA B * C +A B C + *

    A B C D - - -

    A B - C - D -

    + * A B C* A + B C

    - A - B - C D

    - - - A B C D

  • 7/30/2019 Chapter 04 Stacks

    35/43

    Evaluating RPN Expressions

    "By hand" (Underlining technique):1. Scan the expression from left to right to find an operator.

    2. Locate ("underline") the last two preceding operands

    and combine them using this operator.

    3. Repeat until the end of the expression is reached.

    Example:2 3 4 + 5 6 - - *

    2 8 *

    2 8 * 16

    2 7 5 6 - - *2 7 5 6 - - *2 7 -1 - *

    2 7 -1 - *

    2 3 4 + 5 6 - - *

  • 7/30/2019 Chapter 04 Stacks

    36/43

    Stack Algorithm: (p.195)

    Receive: An RPN expression.

    Return: A stack whose top element is the value of RPN expression

    (unless an error occurred).

    1. Initialize an empty stack.

    2. Repeat the following until the end of the expression is

    encountered:

    a. Get next token (constant, variable, arithmetic operator) in

    the RPN expression.

    b. If token is an operand, push it onto the stack.

    If it is an operator, then:

    (i) Pop top two values from the stack. If stack

    does not contain two items, signal error due to a

    malformed RPN and terminate evaluation.(ii)Apply the operatorto these two values.

    (iii) Push the resulting value back onto the stack.

    3. When the end of expression encountered, its value is on top

    of the stack (and, in fact, must be the only value in the stack).

    Push TEMP#

    Generate code:

    LOAD operand1op operand2

    STORE TEMP#:

    A B C + D E - - *

    Sample RPN Evaluation (p 196)

  • 7/30/2019 Chapter 04 Stacks

    37/43

    Sample RPN Evaluation (p. 196)Example: 2 3 4 + 5 6 - - *

    Push 2Push 3Push 4Read+

    Pop4, Pop3,Push 7Push 5Push 6Read -

    Pop6,Pop5,Push -1

    Read-Pop-1, Pop7,

    Push 8Read*

    Pop8, Pop2,

    Push 16

    234

    27

    56

    27

    -1

    28

    16

    3 + 4 = 7

    5 - 6 = -1

    7 - -1 = 8

    2 * 8 = 16

  • 7/30/2019 Chapter 04 Stacks

    38/43

    Which interpretation for the -?

    Example: 5 3 - -

    5 3 - -5 -3 -8

    5 3 - -2 --2

    Use a different symbol:

    5 3 ~ -

    OR

    5 3 - ~

    Unary minus causes problems

    Have ~ stand for negative

    C ti I fi t RPN

  • 7/30/2019 Chapter 04 Stacks

    39/43

    Converting Infix to RPN1. By hand: Represent infix expression as an expression tree:

    A * B + C

    +

    C*

    A B

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

    *

    A +

    B CC

    A B

    D E

    *

    +

    /

    -

    D

    x y

    xD y

    Root Node

    Edge Children Nodes

    (Binary Tree2 kids)

    T th t i L f Ri h P/

  • 7/30/2019 Chapter 04 Stacks

    40/43

    C

    A B

    D E

    *

    +

    /

    -

    Traverse the tree inLeft-Right-Parent

    order (postorder) to get RPN:

    C

    A B

    D E

    *

    +

    /

    -

    Traverse tree in Parent-Left-Right

    order (preorder) to get prefix:

    Traverse tree inLeft-Parent-Right

    order (inorder) to get infixmust insert ()'s

    A B + C * D E - /

    - D E

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

    A B

    D E

    *

    +

    /

    -

    / * + A B C

  • 7/30/2019 Chapter 04 Stacks

    41/43

    2. By hand: "Fully parenthesize-move-erase" method:

    1. Fully parenthesize the expression.

    2. Replace each right parenthesis by the corresponding operator.

    3. Erase all left parentheses.

    Examples:

    A * B + C

    ((A B * C +

    A B * C +

    A * (B + C)

    (A (B C + *

    A B C + *

    Exercise:

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

    ((A * B) + C) (A * (B + C) )

  • 7/30/2019 Chapter 04 Stacks

    42/43

    3. Use a stack! Stack Algorithm: (p.199)

    1. Initialize an empty stack of operators.

    2. While no error has occurred and end of infix expression not reached

    a. Get next token in the infix expression.b. Iftoken is

    (i) a left parenthesis: Push it onto the stack.

    (ii) a right parenthesis: Pop and display stack elements until a left

    parenthesis is encountered, but do not display

    it. (Error if stack empty with no left

    parenthesis found.)

    (iii) an operator: If stack empty or token has higher priority

    than top stack element, push token onto stack.

    (Left parenthesis in stack has lower priority

    than operators)

    Otherwise, pop and display the top stackelement; then repeat the comparison oftoken

    with new top stack item.

    (iv) an operand: Display it.

    3. When end of infix expression reached, pop and display stack items until

    stack is empty.

    ( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))( )/( ( ))

  • 7/30/2019 Chapter 04 Stacks

    43/43

    (-

    /

    Example:Push ( OutputDisplayAPush +

    Display BPush*Display CRead )

    Pop *, Display *,Pop +, Display +, Pop (

    Push /Push (Display DPush -Push (Display E

    Push -Display FRead )

    Pop -, Display -, Pop (

    Read )Pop -, Display -, Pop (

    (

    +*

    (+

    (-(-

    (

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

    A

    ABCAB

    ABC*ABC*+

    ABC*+D

    ABC*+DE

    ABC*+DEF

    ABC*+DEF-

    ABC*+DEF--

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

    /

    /

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