Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, 
© 2005 Pearson Education, Inc. All rights reserved. 0-13-140909-3 

 

 

Figure 7.2 Conversion from Base Ten to Base Two

/*--------------------------------------------------------------
   This program uses a stack to convert the base-ten representation 
   of a positive integer entered as input to base two, which is
   then output.
---------------------------------------------------------------------*/

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

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
  do
  {
    cout << "Enter positive integer to convert: ";
    cin >> number;
    while (number != 0)
      {
	remainder = number % 2;
	stackOfRemainders.push(remainder);
	number /= 2;
      }
    cout << "Base-two representation: ";

    while ( !stackOfRemainders.empty() )
    {
      remainder = stackOfRemainders.top();
      stackOfRemainders.pop();
      cout << remainder;
    }
    cout << endl;
    cout << "\nMore (Y or N)? ";
    cin >> response;
  }
  while (response == 'Y' || response == 'y');
} 

 

 

 

Figure 7.3 Class Declaration for a Stack Type

/*-- Stack.h ---------------------------------------------------
 
  This header file defines a Stack data type.
  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 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 <= myTop < STACK_CAPACITY 

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

#include <iostream>
using namespace std;

#ifndef STACK
#define STACK

const int STACK_CAPACITY = 128;
typedef int StackElement;

class Stack
{
 public:
  /***** Function Members *****/

 private:
  /***** Data Members *****/
  StackElement myArray[STACK_CAPACITY];
  int myTop;
}; 

#endif 

 

 

Figure 7.4A Completed Stack.h File

/*-- Stack.h ---------------------------------------------------
 
  This header file defines a Stack data type.
  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:          Retrieves the top stack value; leaves stack unchanged
    pop:          Modifies 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 <= myTop < STACK_CAPACITY 
--------------------------------------------------------------*/

#include <iostream>

#ifndef STACK
#define STACK

const int STACK_CAPACITY = 128;
typedef int StackElement;

class Stack
{
 public:
  /***** Function Members *****/
  /***** Constructor *****/
  Stack();
  /*----------------------------------------------------------
    Construct a Stack object.

    Precondition:  None.
    Postcondition: An empty Stack object has been constructed
        (myTop is initialized to -1 and myArray is an array
        with STACK_CAPACITY elements of type StackElement).
   -----------------------------------------------------------*/

  bool empty() const;
  /*-----------------------------------------------------------
    Check if stack is empty.
    Precondition: None
    Postcondition: Returns true if stack is empty and 
        false otherwise.
   -----------------------------------------------------------*/

  void push(const StackElement & value);
  /*-----------------------------------------------------------
    Add a value to a stack.

    Precondition: value is to be added to this stack
    Postcondition: value is added at top of stack provided 
        there is space; otherwise, a stack-full message is 
        displayed and execution is terminated.
   -----------------------------------------------------------*/

  void display(ostream & out) const;
  /*-----------------------------------------------------------
    Display values stored in the stack. 

    Precondition:  ostream out is open.
    Postcondition: Stack's contents, from top down, have
        been output to out.
   -----------------------------------------------------------*/

  StackElement top() const;
  /*-----------------------------------------------------------
    Retrieve value at top of stack (if any).

    Precondition:  Stack is nonempty
    Postcondition: Value at top of stack is returned, unless
        the stack is empty; in that case, an error message is
        displayed and a "garbage value" is returned.
   ----------------------------------------------------------*/

  void pop();
  /*-----------------------------------------------------------
    Remove value at top of stack (if any).

    Precondition:  Stack is nonempty.
    Postcondition: Value at top of stack has been removed, 
        unless the stack is empty; in that case, an error 
        message is displayed and execution allowed to proceed.
   ----------------------------------------------------------*/ 

 private:
  /***** Data Members *****/
  StackElement myArray[STACK_CAPACITY];
  int myTop;
}; // end of class declaration

#endif 

 

 

 

Figure 7.4B Stack.cpp File

/*-- Stack.cpp-----------------------------------------------------------
 
   This file implements Stack member functions.

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

#include <iostream>
using namespace std;

#include "Stack.h"

//--- Definition of Stack constructor
Stack::Stack()
: myTop(-1)
{}

//--- Definition of empty()
bool Stack::empty() const
{ 
   return (myTop == -1); 
}

//--- Definition of push()
void Stack::push(const StackElement & value)
{
   if (myTop < STACK_CAPACITY - 1) //Preserve stack invariant
   { 
      ++myTop;
      myArray[myTop] = value;
   }
   else
   {
      cerr << "*** Stack full -- can't add new value ***\n"
              "Must increase value of STACK_CAPACITY in Stack.h\n";
      exit(1);
   }
}

//--- Definition of display()
void Stack::display(ostream & out) const
{
   for (int i = myTop; i >= 0; i--) 
      out << myArray[i] << endl;
}

//--- Definition of top()
StackElement Stack::top() const
{
   if ( !empty() ) 
      return (myArray[myTop]);
   else
   {
      cerr << "*** Stack is empty "
              " -- returning garbage value ***\n";
      return *(new StackElement);
   }
}

//--- Definition of pop()
void Stack::pop()
{
   if ( !empty() )
      myTop--;
   else
      cerr << "*** Stack is empty -- "
              "can't remove a value ***\n";
} 

 

 

 

Figure 7.5  Stack Test Program

/*---------------------------------------------------------------------
                  Driver program to test the Stack class.
  ----------------------------------------------------------------------*/

#include <iostream>
#include <iomanip>
using namespace std;
	
#include "Stack.h"

int main()
{
   Stack s;
   cout << "Stack created.  Empty? " << boolalpha << s.empty() << endl;

   cout << "How many elements to add to the stack? ";
   int numItems;
   cin >> numItems;
   for (int i = 1; i <= numItems; i++) s.push(i);	

   cout << "Stack contents:\n";
   s.display(cout);	
   cout << "Stack empty? " << s.empty() << endl;

   cout << "Top value: " << s.top() << endl;

   while (!s.empty())
   {
     cout << "Popping " << s.top() << endl;
     s.pop();
   }
   cout << "Stack empty? " << s.empty() << endl;
   cout << "Top value: " << s.top() << endl;
   cout << "Trying to pop: " << endl;
   s.pop();
} 

 

 

 

Figure 7.6A DStack.h File

/*-- DStack.h ---------------------------------------------------
 
  This header file defines a Stack data type.
  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 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 <= myTop < myCapacity 

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

#include <iostream>
using namespace std;

#ifndef DSTACK
#define DSTACK

typedef int StackElement;

class Stack
{
 public:
  /***** Function Members *****/
  /***** Constructors *****/
  Stack(int numElements = 128);
  /*----------------------------------------------------------
    Construct a Stack object.

    Precondition:  None.
    Postcondition: An empty Stack object has been constructed
        (myTop is initialized to -1 and myArray is an array
        with numElements (default 128) elements of type 
        StackElement).
  -----------------------------------------------------------*/

  Stack(const Stack & original);
  /*----------------------------------------------------------
    Copy Constructor 

    Precondition:  original is the stack to be copied and 
        is received as a const reference parameter.
    Postcondition: A copy of original has been constructed.
  -----------------------------------------------------------*/

 /***** Destructor *****/
  ~Stack(); 
  /*----------------------------------------------------------
    Class destructor 

    Precondition:  None
    Postcondition: The dynamic array in the stack has been 
      deallocated.
  -----------------------------------------------------------*/

  /***** Assignment *****/
  Stack & operator= (const Stack & original);
  /*----------------------------------------------------------
    Assignment Operator 

   Precondition:  original is the stack to be assigned and 
       is received as a const reference parameter.
   Postcondition: The current stack becomes a copy of 
       original and a reference to it is returned.
  -----------------------------------------------------------*/

  bool empty() const;
  /*-----------------------------------------------------------
    Check if stack is empty.
    Precondition: None
    Postcondition: Returns true if stack is empty and 
        false otherwise.
   -----------------------------------------------------------*/

  void push(const StackElement & value);
  /*-----------------------------------------------------------
    Add a value to a stack.

    Precondition:  value is to be added to this stack
    Postcondition: value is added at top of stack provided 
        there is space; otherwise, a stack-full message is 
        displayed and execution is terminated.
   -----------------------------------------------------------*/

  void display(ostream & out) const;
  /*-----------------------------------------------------------
    Display values stored in the stack. 

    Precondition:  ostream out is open.
    Postcondition: Stack's contents, from top down, have
        been output to out.
   -----------------------------------------------------------*/

  StackElement top() const;
  /*-----------------------------------------------------------
    Retrieve value at top of stack (if any).

    Precondition:  Stack is nonempty
    Postcondition: Value at top of stack is returned, unless
        the stack is empty; in that case, an error message is
        displayed and a "garbage value" is returned.
   ----------------------------------------------------------*/

  void pop();
  /*-----------------------------------------------------------
    Remove value at top of stack (if any).

    Precondition:  Stack is nonempty.
    Postcondition: Value at top of stack has been removed, 
        unless the stack is empty; in that case, an error 
        message is displayed and execution allowed to proceed.
   ----------------------------------------------------------*/ 

 private:
 /***** Data Members *****/
  int myCapacity,           // capacity of stack
      myTop;                // top of stack
  StackElement * myArray;   // dynamic array to store elements

}; // end of class declaration

#endif 

 

 

 

Figure 7.6B DStack.cpp File

/*-- DStack.cpp----------------------------------------------------------
 
   This file implements Stack member functions.

-------------------------------------------------------------------------*/
 
#include <iostream>
#include <cassert>
#include <new>
using namespace std;

#include "DStack.h"

//--- Definition of Stack constructor
Stack::Stack(int numElements)
{
   assert (numElements > 0);  // check precondition
   myCapacity = numElements;  // set stack capacity
                     // allocate array of this capacity
   myArray = new(nothrow) StackElement[myCapacity];
   if (myArray != 0)          // memory available
      myTop = -1;
   else
   {
      cerr << "Inadequate memory to allocate stack \n"
              " -- terminating execution\n";
      exit(1);
   }               // or assert(myArray != 0);
}

//--- Definition of Stack copy constructor
Stack::Stack(const Stack & original)
: myCapacity(original.myCapacity), myTop(original.myTop)
{
   //--- Get new array for copy
   myArray = new(nothrow) StackElement[myCapacity];   
                                     // allocate array in copy

   if (myArray != 0)                 // check if memory available
      // copy original's array member into this new array
      for (int pos = 0; pos < myCapacity; pos++) 
         myArray[pos] = original.myArray[pos];
   else
   {
      cerr << "*Inadequate memory to allocate stack ***\n";
      exit(1);
   }
}

//--- Definition of Stack destructor
Stack::~Stack()
{ 
   delete [] myArray;
}

//--- Definition of assignment operator
Stack & Stack::operator=(const Stack & original)
{
  if (this != &original)                   // check that not st = st
   {
     //-- Allocate a new array if necessary
      if (myCapacity != original.myCapacity) 
      {
	delete[] myArray;                  // destroy previous array

	myCapacity = original.myCapacity;  // copy myCapacity
         myArray = new StackElement[myCapacity]; 
         if (myArray == 0)                  // check if memory available
         {
	   cerr << "*** Inadequate memory ***\n";
            exit(1);
         }
       }
      //--- Copy original's array into this myArray
      for (int pos = 0; pos < myCapacity; pos++) 
         myArray[pos] = original.myArray[pos];

      myTop = original.myTop;              // copy myTop member
   }
   return *this;
}

//--- Definition of empty()
bool Stack::empty() const
{ 
   return (myTop == -1); 
}

//--- Definition of push()
void Stack::push(const StackElement & value)
{
   if (myTop < myCapacity - 1) //Preserve stack invariant
   { 
      ++myTop;
      myArray[myTop] = value;
   }
   else
   {
      cerr << "*** Stack full -- can't add new value ***\n"
              "Must increase value of STACK_CAPACITY in Stack.h\n";
      exit(1);
   }
}

//--- Definition of display()
void Stack::display(ostream & out) const
{
   for (int i = myTop; i >= 0; i--) 
      out << myArray[i] << endl;
}

//--- Definition of top()
StackElement Stack::top() const
{
   if ( !empty() ) 
      return (myArray[myTop]);
   else
   {
      cerr << "*** Stack is empty "
              " -- returning garbage value ***\n";
      return *(new StackElement);
   }
}

//--- Definition of pop()
void Stack::pop()
{
   if ( !empty() )
      myTop--;
   else
      cerr << "*** Stack is empty -- "
              "can't remove a value ***\n";
} 

 

 

 

Figure 7.10 Test Program for DStack Class

/*---------------------------------------------------------------------
                  Driver program to test the Stack class.
  ----------------------------------------------------------------------*/

#include <iostream>
#include <iomanip>
using namespace std;
	
#include "DStack.h"

void print(Stack st)
{ st.display(cout); }

int main()
{
   int cap;
   cout << "Enter stack capacity: ";
   cin >> cap;

   Stack s(cap);
   cout << "Stack created.  Empty? " << boolalpha << s.empty() << endl;

   cout << "How many elements to add to the stack? ";
   int numItems;
   cin >> numItems;
   for (int i = 1; i <= numItems; i++) 
      s.push(i);
   cout << "Stack empty? " << s.empty() << endl;

   cout << "Contents of stack s (via  print):\n";
   print(s); cout << endl;
   cout << "Check that the stack wasn't modified by print:\n";
   s.display(cout); cout << endl;

   Stack t, u;
   t = u = s;
   cout << "Contents of stacks t and u after t = u = s (via  print):\n";
   cout << "u:\n"; print(u); cout << endl;
   cout << "t:\n"; print(t); cout << endl;

   cout << "Top value in t: " << t.top() << endl;

   while (!t.empty())
   {
     cout << "Popping t:  " << t.top() << endl;
     t.pop();
   }
   cout << "Stack t empty? " << t.empty() << endl;
   cout << "\nNow try to retrieve top value from t." << endl;
   cout << "Top value in t: " << t.top() << endl;
   cout << "\nTrying to pop t: " << endl;
   t.pop();
} 

 

 

 

Figure 7.11 Linked-List-Based 
Declaration for
Stack Class

class Stack
{
 public:
 /***** Function Members *****/
 // Prototypes same as in preceding section

 private:
    /*** Node class ***/
   class Node
   {
    public:
      StackElement data;
      Node * next;
      //--- Node constructor
      Node(StackElement value, Node * link = 0)
      /*------------------------------------------------------
        Precondition:  value is received
        Postcondition: A Node has been constructed with value
            in its data part and itb next part set to link
            (default 0).
       ------------------------------------------------------*/
      { data = value; next = link; }

  };

  typedef Node * NodePointer;

  /***** Data Members *****/
  NodePointer myTop;      // pointer to top of stack

}; // end of class declaration 

 

 

 

Figure 7.12 LStack.cpp Implementation

//--- LStack.cpp -------------------------------------------------
 
#include <new>
using namespace std;

#include "LStack.h"

//--- Definition of Stack constructor
Stack::Stack()
: myTop(0)
{}

//--- Definition of Stack copy constructor
Stack::Stack(const Stack & original)
{
   myTop = 0;
   if (!original.empty())
   {
      // Copy first node
      myTop = new Stack::Node(original.top());

      // Set pointers to run through the stack's linked lists
      Stack::NodePointer lastPtr = myTop,
                         origPtr = original.myTop->next;

      while (origPtr != 0)
      {
         lastPtr->next = new Stack::Node(origPtr->data);
         lastPtr = lastPtr->next;
         origPtr = origPtr->next;
      }
   }
}

//--- Definition of Stack destructor
Stack::~Stack()
{     
   // Set pointers to run through the stack
   Stack::NodePointer currPtr = myTop,  // node to be deallocated
                      nextPtr;          // its successor
   while (currPtr != 0)
   {
      nextPtr = currPtr->next;
      delete currPtr;
      currPtr = nextPtr;
   }
}

//--- Definition of assignment operator
Stack & Stack::operator=(const Stack & original)
{
   myTop = 0;
   if (original.empty()) return *this;

   if (this != &original)     // check that not st = st
   {
      this->~Stack();         // destroy current linked list
 
      // Copy first node
      myTop = new Stack::Node(original.top());

      // Set pointers to run through the stacks' linked lists
      Stack::NodePointer lastPtr = myTop,
                         origPtr = original.myTop->next;

      while (origPtr != 0)
        {
          lastPtr->next = new Stack::Node(origPtr->data);
          lastPtr = lastPtr->next;
          origPtr = origPtr->next;
        } 
   }
   return *this;
}

//--- Definition of empty()
bool Stack::empty() const
{ 
   return (myTop == 0); 
}

//--- Definition of push()
void Stack::push(const StackElement & value)
{
   myTop = new Stack::Node(value, myTop);
}

//--- Definition of display()
void Stack::display(ostream & out) const
{
   Stack::NodePointer ptr;
   for (ptr = myTop; ptr != 0; ptr = ptr->next)
      out << ptr->data << endl;
}

//--- Definition of top()
StackElement Stack::top() const
{
   if (!empty())
      return (myTop->data);
   else
   {
      cerr << "*** Stack is empty "
              " -- returning garbage ***\n";
      return *(new StackElement);   // "Garbage" value
   }
}

//--- Definition of pop()
void Stack::pop()
{
   if (!empty())
   {
      Stack::NodePointer ptr = myTop;
      myTop = myTop->next;
      delete ptr;
   }   
   else
      cerr << "*** Stack is empty -- can't remove a value ***\n";
} 

 

 

 

Figure 7.12C Driver Program for Linked List Implementation of Stack

/*---------------------------------------------------------------------
                  Driver program to test the Stack class.
  ----------------------------------------------------------------------*/

#include <iostream>
using namespace std;
	
#include "LStack.h"

void print(Stack st)
{ st.display(cout); }

int main()
{
   Stack s;
   cout << "Stack created.  Empty? " << boolalpha << s.empty() << endl;

   cout << "How many elements to add to the stack? ";
   int numItems;
   cin >> numItems;
   for (int i = 1; i <= numItems; i++) 
      s.push(i);	
   cout << "Stack empty? " << s.empty() << endl;

   cout << "Contents of stack s (via  print):\n";
   print(s); cout << endl;
   cout << "Check that the stack wasn't modified by print:\n";
   s.display(cout); cout << endl;

   Stack t, u;
   t = u = s;
   cout << "Contents of stacks t and u after t = u = s (via  print):\n";
   cout << "u:\n"; print(u); cout << endl;
   cout << "t:\n"; print(t); cout << endl;

   cout << "Top value in t: " << t.top() << endl;

   while (!t.empty())
   {
     cout << "Popping t:  " << t.top() << endl;
     t.pop();
   }
   cout << "Stack t empty? " << t.empty() << endl;
   cout << "\nNow try to retrieve top value from t." << endl;
   cout << "Top value in t: " << t.top() << endl;
   cout << "\nTrying to pop t: " << endl;
   t.pop();
} 

 

 

 

Figure 7.15 Converting Infix to Postfix

/*--------------------------------------------------------------------------
   Convert infix expressions to postfix.
 
   Input:  An infix expression and user responses
   Output: The postfix expression
--------------------------------------------------------------------------*/

#include <iostream>	  // <<, >>, cout, cin
#include <string>         // string, ==, find, npos
#include <cassert>        // assert()
#include <cctype>         // alnum()
using namespace std;
#include "DStack.h"       // Stack class with StackElement = char

string postfix(string exp);

int main()
{
   string exp;            // infix expression
   cout << "NOTE: Enter # for infix expression to stop.\n";
   for (;;)
   {
      cout << "\nInfix expression? ";
      getline(cin, exp);

      if (exp == "#") break;

      cout << "Postfix expression is " << postfix(exp) << endl;
   }
}

string postfix(string exp)
/*-------------------------------------------------------------------------
   Function to convert an infix expression exp to postfix.

   Precondition:  exp is received
   Postcondition: postfix expression corresponding to exp is returned
       or an error message displayed if an error was found in exp.
-------------------------------------------------------------------------*/
{
   char token,                   // character in exp
        topToken;                // token on top of opStack
   Stack opStack;                // stack of operators
   string RPNexp;                // postfix expression
   const string BLANK = " ";
   for (int i = 0; i < exp.length(); i++)
   {
      token = exp[i];
      switch(token)
      {
         case ' ' : break;       // do nothing -- skip blanks
         case '(' : opStack.push(token);
                    break;
         case ')' : for (;;)
                    {
                       assert (!opStack.empty());
                       topToken = opStack.top();
                       opStack.pop();
                       if (topToken == '(') break;
                       RPNexp.append(BLANK + topToken);
                    }
                    break;
         case '+' : case '-' :
         case '*' : case '/': case'%':
                    for (;;)
                    {
                       if (opStack.empty() ||
                           opStack.top() == '(' ||
                           (token == '*' || token == '/' || token == '%') &&
                           (opStack.top() == '+' || opStack.top() == '-'))
                       {
                          opStack.push(token);
                          break;
                       }
                       else
                       {
                          topToken = opStack.top();
                          opStack.pop();
                          RPNexp.append(BLANK + topToken);
                       }
                    }
                    break;
         default :  // operand
  	            RPNexp.append(BLANK + token);
                    for(;;)
		    {
                       if ( !isalnum(exp[i+1]) ) break;  // end of identifier
		       i++;
		       token = exp[i];
		       RPNexp.append(1, token);
		    }
      }
   }
   // Pop remaining operators on the stack
   for (;;)
   {
      if (opStack.empty()) break;
      topToken = opStack.top();
      opStack.pop();
      if (topToken != '(')
      {
         RPNexp.append(BLANK + topToken);
      }
      else
      {
         cout << " *** Error in infix expression ***\n";
         break;
      }
   }
   return RPNexp;
} 

 

 

 

Figure

 

 

 

 

Figure

 

 

 

 

Figure

 

 

 

 

Figure

 

 

 

 

Figure

 

 

 

 

Figure

 

 

 

 

Figure