Saturday, February 24, 2018

Programming Challenge 16.8 - SimpleVector Modification

Example Files: SimpleVectorModification.7z

Notice: Most of the code for this program is taken from chapter 16, pp. 1015 through 1019 in the 9th Edition, or pp. 997 through 1001 in the 8th Edition of this book.

SimpleVector.h


#ifndef SIMPLE_VECTOR_H_
#define SIMPLE_VECTOR_H_

#include <cstdlib>
#include <iostream>
#include <new>

template <class T>
class SimpleVector
{
    private:
        T    *aptr;
        int arraySize;
        int maxCapacity;

        void memError();
        void subError();

        template <class TPrint>
        friend std::ostream &operator << (std::ostream &, const SimpleVector<TPrint> &);

    public:
        SimpleVector();
        SimpleVector(int);
        SimpleVector(const SimpleVector &);
        ~SimpleVector();

        // Mutator functions
        void push_back(const T &);
        void pop_back();

        // Accessor functions
        int getArraySize() const
        { return arraySize; }
       
        T getElementAt(int);   
        T &operator [](const int &);
};

/* **********************************************************
            SimpleVector<T>::SimpleVector() - Constructor
   ********************************************************** */

template <class T>
SimpleVector<T>::SimpleVector()
{
    arraySize = 0;
    maxCapacity = 0;
}

/* **********************************************************
            SimpleVector<T>::SimpleVector() - Constructor
   ********************************************************** */

template <class T>
SimpleVector<T>::SimpleVector(int arrSize)
{
    arraySize = arrSize;

    try
    {
        aptr = new T[arrSize];
    }
    catch (std::bad_alloc)
    {
        memError();
    }

    for (int count = 0; count < arraySize; count++)
    {
        *(aptr + count) = 0;
    }
}
   
/* **********************************************************
            SimpleVector<T>::SimpleVector() - Copy Constructor
   ********************************************************** */

template <class T>
SimpleVector<T>::SimpleVector(const SimpleVector &obj)
{
    arraySize = obj.arraySize;

    aptr = new T[arraySize];

    if (aptr == 0)
    {
        memError();
    }

    for (int count = 0; count < arraySize; count++)
    {
        *(aptr + count) = *(obj.aptr + count);
    }
}

/* **********************************************************
            SimpleVector<T>::~SimpleVector() - Destructor
   ********************************************************** */

template <class T>
SimpleVector<T>::~SimpleVector()
{
    if (arraySize > 0)
    {
        delete [] aptr;
    }
}

/* **********************************************************
            SimpleVector<T>::pushBack() : const T, int &
    This function emulates a vector's push_back function. It
    dynamically allocates a temporary array of size n+1, then
    copies the original array's values to it. Next, the last
    element of the new array is assigned the tempVal's value
    before the original array is deleted. Before returning,
    the original array is caused to point to the new array,
    and the arraySize member variable gets incremented.
   ********************************************************** */

template <class T>
void SimpleVector<T>::push_back(const T &tempVal)
{
    T *tempAptr = new T[arraySize + 1];

    for (int count = 0; count < arraySize; count++)
    {
        *(tempAptr + count) = *(aptr + count);
    }
   
    delete[] aptr;
    aptr = tempAptr;
   
    *(aptr + arraySize) = tempVal;

    arraySize++;
}

/* **********************************************************
            SimpleVector<T>::pop_back() : int &
    This function emulates a vector's pop_back function. If
    arraySize is greater 0, the maxCapacity and arraySize will
    get decremented. Next, a temporary array is dynamically
    allocated, to which the original array's values n-1 are
    copied. Then, the original array is deleted, and caused to
    point to the new array. Otherwise, the memError() function
    is called, and the program exits with an error message.
   ********************************************************** */

template <class T>
void SimpleVector<T>::pop_back()
{
    if (arraySize > 0)
    {
        maxCapacity = --arraySize;

        T *tempPtr = new T[maxCapacity];

        for (int count = 0; count < maxCapacity; count++)
        {
            *(tempPtr + count) = *(aptr + count);
        }

        delete[] aptr;
        aptr = tempPtr;
    }
    else
    {
        memError();
    }
}

/* **********************************************************
            T SimpleVector<T>::getElementAt() : int
    This function returns the value stored at the subscript
    in the array.
   ********************************************************** */

template <class T>
T SimpleVector<T>::getElementAt(int subPos)
{
    if (subPos < 0 || subPos >= arraySize)
    {
        subError();
    }

    return aptr[subPos];
}

/* **********************************************************
            T &SimpleVector<T>::operator[]() : const int &
         - Overloaded [] operator
    This function returns a reference to the element in the
    array indexed by the subscript.
   ********************************************************** */

template <class T>
T &SimpleVector<T>::operator[](const int &subPos)
{
    if (subPos < 0 || subPos >= arraySize)
    {
        subError();
    }

    return aptr[subPos];
}

/* **********************************************************
            SimpleVector<T>::subError()
    Displays an error message and terminates the program when
    a subscript is out of range.
    ********************************************************** */

template <class T>
void SimpleVector<T>::subError()
{
    cout << "ERROR: Subscript out of range.\n";
    cin.get();
    cin.ignore();
    exit(EXIT_FAILURE);
}

/* **********************************************************
            SimpleVector<T>::memError()
    Displays an error message and terminates the program when
    memory allocation fails.
   ********************************************************** */

template <class T>
void SimpleVector<T>::memError()
{
    cout << "ERROR: Cannot allocate memory.\n";
    cout << "This program will now exit ...\n";
    std::cin.get();
    std::cin.ignore();
    exit(EXIT_FAILURE);
}

/* **********************************************************
            Overloaded Extraction Operator <<
   ********************************************************** */

template <class T>
std::ostream &operator << (std::ostream &strm, const SimpleVector<T> &obj)
{
    for (int count = 0; count < obj.arraySize; count++)
    {
        strm << (*(obj.aptr + count)) << ' ';
    }

    return strm;
}

#endif

SimpleVectorMod.cpp


#include "SimpleVector.h"

#include <iostream>
using std::cin;
using std::cout;

/* **********************************************************
                            Function Definition
   ********************************************************** */

void printIntro(const int);

int main()
{
    int     SIZE = 10;
    int     count = 0;
    int     intVal = 0;
    double doubleVal = 0;
    char   characterVal = ' ';
    char     choice = ' ';
   
    SimpleVector<int>        intTable(SIZE);
    SimpleVector<double> doubleTable(SIZE);
    SimpleVector<char>   charTable(SIZE);

    printIntro(SIZE);

    cout << "Now filling the arrays with initial values. Please be patient!\n";
    for (; count < SIZE; count++)
    {
        intTable[count] = (count * 2);
        doubleTable[count] = (count * 2.14);
        charTable[count] = count;
    }

    cout << "\nThese are the values currently in your intTable:\n";
    cout << intTable << "\n\n";
    cout << "These are the values currently in your doubleTable:\n";
    cout << doubleTable << "\n\n";
    cout << "These are the values currently in your charTable:\n";
    cout << charTable << "\n\n";

    do
    {
        cout << "Please enter an int value: ";
        cin >> intVal;
        intTable.push_back(intVal);

        cout << "Please enter a floating-point value (Ex: 7.5): ";
        cin >> doubleVal;
        doubleTable.push_back(doubleVal);

        cout << "Please enter a character: ";
        cin >> characterVal;   
        charTable.push_back(characterVal);

        cout << "\nDo you wish to add another set of values (Y/N)? ";
        cin >> choice;
        cout << "\n";

        while (toupper(choice) != 'Y' && toupper(choice) != 'N')
        {
            cout << "\nDo you wish to add another set of values (Y/N)? ";
            cin >> choice;
        }
    } while (toupper(choice) != 'N');

    cout << "These are the values now in your intTable:\n";
    cout << intTable << "\n\n";
    cout << "These are the values now your doubleTable:\n";
    cout << doubleTable << "\n\n";
    cout << "These are the values now in your charTable:\n";
    cout << charTable << "\n\n";

    cout << "Some values will no be removed from your arrays.\n";
    for (count = intTable.getArraySize(); count > 4; count--)
    {
        intTable.pop_back();
        doubleTable.pop_back();
        charTable.pop_back();
    }

    cout << "\nThese are the new values in your intTable:\n";
    cout << intTable << "\n\n";
    cout << "These are the new values in your doubleTable:\n";
    cout << doubleTable << "\n\n";
    cout << "These are the new values in your charTable:\n";
    cout << charTable << "\n\n";

    cout << "This is the end of the Simple Vector demo. Have a nice day!";

    cin.get();
    cin.ignore();
   return 0;
}

/* **********************************************************
            printIntro() : const int
    Outputs information about the program's purpose and
    functionality.
   ********************************************************** */

void printIntro(const int SIZE)
{
    cout << "SIMPLE VECTOR DEMO\n\n";
    cout << "This program emulates functionality in the STL vector class:\n"
           << "   1.] push_back()\n"
          << "   2.] pop_back()\n\n";
    cout << "The program will fill two arrays with an initial set of "
          << SIZE << " values.\n";
    cout << "Then, you are asked to input an integer, a floating-point value,\n"
          << "and a character, which are added to the appropriate array, to\n"
         << "demonstrate how the push_back() function works.\n";
    cout << "Before the program exits, some values will be removed from the\n"
          << "arrays, to demonstrate how the pop_back() function works.\n\n";
}

Example Output:





No comments:

Post a Comment