
Data Structure

This illustrates a data structure, a means of storing data within a program.

You may see other such structures in the Data Structures category.
A stack is a container of elements with   last in, first out   access policy.   Sometimes it also called LIFO.

The stack is accessed through its top.

The basic stack operations are:

   push   stores a new element onto the stack top;
   pop   returns the last pushed stack element, while removing it from the stack;
   empty   tests if the stack contains no elements.


Sometimes the last pushed stack element is made accessible for immutable access (for read) or mutable access (for write):

   top   (sometimes called peek to keep with the p theme) returns the topmost element without modifying the stack.


Stacks allow a very simple hardware implementation.

They are common in almost all processors.

In programming, stacks are also very popular for their way (LIFO) of resource management, usually memory.

Nested scopes of language objects are naturally implemented by a stack (sometimes by multiple stacks).

This is a classical way to implement local variables of a re-entrant or recursive subprogram. Stacks are also used to describe a formal computational framework.

See stack machine.

Many algorithms in pattern matching, compiler construction (e.g. recursive descent parsers), and machine learning (e.g. based on tree traversal) have a natural representation in terms of stacks.



Task

Create a stack supporting the basic operations: push, pop, empty.



See also

 Array
 Associative array: Creation, Iteration
 Collections
 Compound data type
 Doubly-linked list: Definition, Element definition, Element insertion, List Traversal, Element Removal
 Linked list
 Queue: Definition, Usage
 Set
 Singly-linked list: Element definition, Element insertion, List Traversal, Element Removal
 Stack


 
report z_stack.
 
interface stack.
  methods:
    push
      importing
        new_element      type any
      returning
        value(new_stack) type ref to stack,
 
    pop
      exporting
        top_element      type any
      returning
        value(new_stack) type ref to stack,
 
    empty
      returning
        value(is_empty) type abap_bool,
 
    peek
      exporting
        top_element type any,
 
    get_size
      returning
        value(size) type int4,
 
    stringify
      returning
        value(stringified_stack) type string.
endinterface.
 
 
class character_stack definition.
  public section.
    interfaces:
      stack.
 
 
    methods:
      constructor
        importing
          characters type string optional.
 
 
  private section.
    data:
      characters type string.
endclass.
 
 
class character_stack implementation.
  method stack~push.
    characters = |{ new_element }{ characters }|.
 
    new_stack = me.
  endmethod.
 
 
  method stack~pop.
    if not me->stack~empty( ).
      top_element = me->characters(1).
 
      me->characters = me->characters+1.
    endif.
 
    new_stack = me.
  endmethod.
 
 
  method stack~empty.
    is_empty = xsdbool( strlen( me->characters ) eq 0 ).
  endmethod.
 
 
  method stack~peek.
    check not me->stack~empty( ).
 
    top_element = me->characters(1).
  endmethod.
 
 
  method stack~get_size.
    size = strlen( me->characters ).
  endmethod.
 
 
  method stack~stringify.
    stringified_stack = cond string(
      when me->stack~empty( )
      then `empty`
      else me->characters ).
  endmethod.
 
 
  method constructor.
    check characters is not initial.
 
    me->characters = characters.
  endmethod.
endclass.
 
 
class integer_stack definition.
  public section.
    interfaces:
      stack.
 
 
    methods:
      constructor
        importing
          integers type int4_table optional.
 
 
  private section.
    data:
      integers type int4_table.
endclass.
 
 
class integer_stack implementation.
  method stack~push.
    append new_element to me->integers.
 
    new_stack = me.
  endmethod.
 
 
  method stack~pop.
    if not me->stack~empty( ).
      top_element = me->integers[ me->stack~get_size( ) ].
 
      delete me->integers index me->stack~get_size( ).
    endif.
 
    new_stack = me.
  endmethod.
 
 
  method stack~empty.
    is_empty = xsdbool( lines( me->integers ) eq 0 ).
  endmethod.
 
 
  method stack~peek.
    check not me->stack~empty( ).
 
    top_element = me->integers[ lines( me->integers ) ].
  endmethod.
 
 
  method stack~get_size.
    size = lines( me->integers ).
  endmethod.
 
 
  method stack~stringify.
    stringified_stack = cond string(
      when me->stack~empty( )
      then `empty`
      else reduce string(
        init stack = ``
        for integer in me->integers
        next stack = |{ integer }{ stack }| ) ).
  endmethod.
 
 
  method constructor.
    check integers is not initial.
 
    me->integers = integers.
  endmethod.
endclass.
 
 
start-of-selection.
  data:
    stack1        type ref to stack,
    stack2        type ref to stack,
    stack3        type ref to stack,
 
    top_character type char1,
    top_integer   type int4.
 
  stack1 = new character_stack( ).
  stack2 = new integer_stack( ).
  stack3 = new integer_stack( ).
 
  write: |Stack1 = { stack1->stringify( ) }|, /.
  stack1->push( 'a' )->push( 'b' )->push( 'c' )->push( 'd' ).
  write: |push a, push b, push c, push d -> Stack1 = { stack1->stringify( ) }|, /.
  stack1->pop( )->pop( importing top_element = top_character ).
  write: |pop, pop and return element -> { top_character }, Stack1 = { stack1->stringify( ) }|, /, /.
 
  write: |Stack2 = { stack2->stringify( ) }|, /.
  stack2->push( 1 )->push( 2 )->push( 3 )->push( 4 ).
  write: |push 1, push 2, push 3, push 4 -> Stack2 = { stack2->stringify( ) }|, /.
  stack2->pop( )->pop( importing top_element = top_integer ).
  write: |pop, pop and return element -> { top_integer }, Stack2 = { stack2->stringify( ) }|, /, /.
 
  write: |Stack3 = { stack3->stringify( ) }|, /.
  stack3->pop( ).
  write: |pop -> Stack3 = { stack3->stringify( ) }|, /, /.
 