Write a C++ program that will sort a template array of data using the following guidelines

Question:

Write a C++ program that will sort a template array of data using the following guidelines –

1. Ask the user for the number of elements, not to exceed SORT_MAX_SIZE = 16 (put appropriate input validation)

2. Ask the user for the type of data they will enter – int, string, or Dollar.

3. Based on the input, create an appropriate array using your template array class.

4. Make sure your template class is contained in one file which does not contain either the main or the sort function of step 4 below. The class declaration should contain NO inline code.

5. Your code should have a function called RecurSelectionSort such that:

It is not part of your Array template class,

Takes in the same type of parameters as any standard SelectionSort with recursion behavior, i.e.

void SelectionSort( arr[], int size)

the trick is to overload and uses the [] operator

Prints out how the array looks every time a recursive step returns back to its caller,

You can use it to sort the three Arrays created in Step 2/3 in descending order.

6. Allow the user to enter data of their own choosing up to their chosen array size. There is no sample output – you are allowed to provide user interactivity as you see fit but programs will be graded for clarity of interaction.

7. Then sort the array using your sort function of step 4.

Answer:

Working code implemented in C++ and appropriate comments provided for better understanding:

Here I am attaching code for these 7 files:

main.cpp
Dollar.cpp
Dollar.h
Currency.cpp
Currency.h
SelectionSort.h
ArrayTemplateClass.h
Source code for main.cpp:

#include <iostream>
#include <fstream>
#include <ostream>
#include <iomanip>
#include <string>
#include "ArrayTemplateClass.h"
#include "Dollar.h"
#include "SelectionSort.h"

using namespace std;


//*********************************************************************************
// int main() - Main declares defines 3 arrays of max size 16, int, string, dollar
// asks the user for the size of the array and the type of array.
// A menu is used to record the user input
// The user can use the menu to sort the arrays in the descending order
//
// PSEUDOCODE:
//
// While not done
//   enter the number of items to process
//   enter the type of items to process
//   enter each item upto the prev specified number.
//   sort items in descending order and provide+log output.
//   ask if done
//       exit
//   else restart
//  
//********************************************************************************
int main()
{
   const int SORT_MAX_SIZE = 16;
   Array<int> aIntArray(SORT_MAX_SIZE);       // An array of type int using Array Template
   Array<string> aStringArray(SORT_MAX_SIZE);   // An array of type String using Array Template
   Array<Dollar> aDollarArray(SORT_MAX_SIZE);   // An array of type Dollar using Array Template

   // handle logging file setup
   // in the initial case we just creat the file and then close it
   ofstream exelog;
   exelog.open("Log.txt");
   exelog << "Names : Author Name\n";
   exelog << "Class : Class ID\n\n";
   exelog.close();

   bool loop = true;   // Exit condition

   while (loop)
   {
       int choice = 0;

       int user_size;

       // User input for size of array
       cout << " How many elements would you like to sort today (1-16)"
           << endl << " ";
       cin >> user_size;

       //Validate user input
       while (user_size < 1 || user_size > SORT_MAX_SIZE)
       {
           cout << " Please enter a valid value between 1 and 16"
               << endl << " ";
           cin >> user_size;
       }

       // Menu for array type
       cout << " What type of data would you like to enter?" << endl;
       cout << " 1: Integer(int)" << endl;
       cout << " 2: String" << endl;
       cout << " 3: Dollar" << endl;
       cout << " 4: Exit" << endl;
       cout << " Your Choice: ";

       // User response recorded
       cin >> choice;
       cout << endl << endl;

       // This switch will execute all actions from the menu
       switch (choice)
       {
       case 1: // Process an Integer array
           cout << " Please enter the integers you would like to sort" << endl
               << " Hit enter after each integer " << endl
               << " (1-16 integers max)" << endl << " ";
           for (int i = 0; i < user_size; i++)
           {
               cin >> aIntArray[i];
               cout << " ";
           }
           exelog.open("Log.txt", ios::app);
           exelog << "\n +++++++++++++++" << endl;
           cout << "\n +++++++++++++++" << endl;
           exelog.close();
           recurSelectionSort(aIntArray, user_size);
           exelog.open("Log.txt", ios::app);
           cout << " ===============" << endl << endl;
           exelog << " ===============" << endl << endl;
           exelog.close();
           break;
       case 2: // Process a string array
           cout << " Please enter the strings you would like to sort" << endl
               << " One word strings only!" << endl
               << " Hit enter after each string " << endl
               << " (1-16 strings max)" << endl << " ";
           for (int i = 0; i < user_size; i++)
           {
               cin >> aStringArray[i];
               cout << " ";
           }
           exelog.open("Log.txt", ios::app);
           exelog << "\n +++++++++++++++" << endl;
           cout << "\n +++++++++++++++" << endl;
           exelog.close();
           recurSelectionSort(aStringArray, user_size);
           cout << " ===============" << endl << endl;
           exelog << " ===============" << endl << endl;
           exelog.close();
           break;
       case 3: // Process a dollar array

           cout << " Please enter the dollar and cent amounts you would like to sort" << endl
               << " Hit enter after each dollar and cent amount " << endl;
           for (int i = 0; i < user_size; i++)
           {
               cin >> aDollarArray[i];
           }
           exelog.open("Log.txt", ios::app);
           exelog << "\n +++++++++++++++" << endl;
           cout << "\n +++++++++++++++" << endl;
           recurSelectionSort(aDollarArray, user_size);
           cout << " ===============" << endl << endl;
           exelog << " ===============" << endl << endl;
           exelog.close();
           break;
       case 4: // We are done. Exiting now.
           cout << " Exiting Program" << endl << endl;
           loop = false;
           break;
       default: // We re-prompt the user to input a correnct menu option.
           cout << " Please enter a valid choice between"
               << " 1-3" << endl;
           break;
       }
   }
   return 0; // Program Finished
}

Source code for Dollar.cpp:

#include "Dollar.h"

// Constructor
Dollar::Dollar(int wPart, int fPart)
{
   wholePart = wPart;
   fractionalPart = fPart;
   normalize();
}

// Destructor
Dollar::~Dollar()
{
}

//************************************************************
// Overloaded > operator. Returns true if the current object *
// is set to a value greater than that of right. *
//************************************************************
bool Dollar::operator>(const Dollar &right)
{
   bool status;

   if (wholePart > right.wholePart)
       status = true;
   else if (wholePart == right.wholePart && fractionalPart > right.fractionalPart)
       status = true;
   else
       status = false;

   return status;
}

//********************************************************
// Overloaded << operator. Gives cout the ability to *
// directly display Dollar objects. *
//********************************************************
std::ostream & operator<<(std::ostream &strm, const Dollar &obj)
{
   std::string stp(".");
   std::string decp0(".0");
   if (obj.fractionalPart < 10)
       stp = ".0";

   strm << obj.wholePart << stp.c_str() << obj.fractionalPart << " ";

   //strm << obj.wholePart << "." << obj.fractionalPart << " ";
   //strm << obj.wholePart << " dollars and " << obj.fractionalPart
   //   << " cents. ($" << obj.wholePart << "." << obj.fractionalPart << ")" << std::endl;

   return strm;
}

//********************************************************
// Overloaded >> operator. Gives cin the ability to *
// store user input directly into Dollar objects. *
//********************************************************
std::istream & operator>>(std::istream &strm, Dollar &obj)
{
   // Prompt the user for the feet.
   std::cout << " Enter dollars: ";
   strm >> obj.wholePart;

   // Prompt the user for the inches.
   std::cout << " Enter cents: ";
   strm >> obj.fractionalPart;

   // Normalize the values.
   obj.normalize();

   return strm;
}

Source code for Dollar.h:

#pragma once

#include "Currency.h"

class Dollar; // Forward Declaration

// Function Prototypes for Overloaded Stream Operators
std::ostream &operator << (std::ostream &, const Dollar &);
std::istream &operator >> (std::istream &, Dollar &);

//**********************************************************************//
// class Dollar - This is the derived Dollar container. //
//**********************************************************************//
class Dollar :
   public Currency
{
public:
   Dollar(int wPart = 0, int fPart = 0);
   ~Dollar();

   //**********************************************************************//
   // Dollar operator > //
   // pre: currency objects we want to compare. //
   // return: result of comparing the operands (>) //
   //**********************************************************************//
   bool operator > (const Dollar &);       // Overloaded >

   // istream and ostream overloading
   // Friends them..
   //**********************************************************************//
   // Dollar output stream operator << //
   // pre: A Dollar object we want to display //
   // return: formatted display data //
   //**********************************************************************//
   friend std::ostream &operator << (std::ostream &, const Dollar &);

   //**********************************************************************//
   // Dollar input stream operator >> //
   // pre: a Dollar object we wan to initialize with user input //
   // return: properly initialized Dollar object //
   //**********************************************************************//
   friend std::istream &operator >> (std::istream &, Dollar &);
};

Source code for Currency.cpp:

#include <cstdlib>
#include "Currency.h"


//************************************************************
// Definition of member function normalize. This function *
// checks for values in the inches member greater than *
// 10 or less than 0. If such a value is found, the numbers *
// in wholePart and fractionalPart are adjusted to conform *
// to our whole to part ratio of 1 whole is 100 parts. *
// *
// For example: *
// 2 wholePart's and 140 fractionaPart's would be adjusted *
// to 3 wholePart's and 40 fractionalPart's. *
//************************************************************

void Currency::normalize()
{
   if (fractionalPart >= 100)
   {
       wholePart += (fractionalPart / 100);
       fractionalPart = fractionalPart % 100;
   }
   else if (fractionalPart < 0)
   {
       wholePart -= ((abs(fractionalPart) / 100) + 1);
       fractionalPart = 100 - (abs(fractionalPart) % 100);
   }
}

Currency Currency::operator+(const Currency &right)
{
   Currency temp;

   temp.fractionalPart = fractionalPart + right.fractionalPart;
   temp.wholePart = wholePart + right.wholePart;
   temp.normalize();
   return temp;
}

Currency Currency::operator-(const Currency &right)
{
   Currency temp;

   temp.fractionalPart = fractionalPart - right.fractionalPart;
   temp.wholePart = wholePart - right.wholePart;
   temp.normalize();
   return temp;
}

//************************************************************
// Overloaded > operator. Returns true if the current object *
// is set to a value greater than that of right. *
//************************************************************

bool Currency::operator > (const Currency &right)
{
   bool status;

   if (wholePart > right.wholePart)
       status = true;
   else if (wholePart == right.wholePart && fractionalPart > right.fractionalPart)
       status = true;
   else
       status = false;

   return status;
}

//************************************************************
// Overloaded < operator. Returns true if the current object *
// is set to a value less than that of right. *
//************************************************************

bool Currency::operator < (const Currency &right)
{
   bool status;

   if (wholePart < right.wholePart)
       status = true;
   else if (wholePart == right.wholePart && fractionalPart < right.fractionalPart)
       status = true;
   else
       status = false;

   return status;
}

//*************************************************************
// Overloaded == operator. Returns true if the current object *
// is set to a value equal to that of right. *
//*************************************************************

bool Currency::operator == (const Currency &right)
{
   bool status;

   if (wholePart == right.wholePart && fractionalPart == right.fractionalPart)
       status = true;
   else
       status = false;

   return status;
}

//*************************************************************
// Overloaded = operator. Assigns the value of the operand on *
// the left of the "=" to the right.                       *
// Returns a pointer to the updated object.                   *
//*************************************************************
Currency& Currency::operator=(const Currency &right)
{
   if (this != &right) {
       this->wholePart = right.wholePart;
       this->fractionalPart = right.fractionalPart;
   }
   return *this;
}

Source code for Currency.h:

#pragma once
#include <iostream>

//**********************************************************************//
// class Currency - This is the base class for our Wallet currencies. //
//**********************************************************************//
class Currency
{
protected:
   int wholePart; // To hold a number of feet
   int fractionalPart; // To hold a number of inches
   void normalize(); // Defined in FeetInches.cpp
public:
   // Constructor
   //
   // post: a Currency object with 0.0 units for the whole and fractional
   // parts.   
   Currency(int wPart = 0, int fPart = 0)
   {
       wholePart = wPart;
       fractionalPart = fPart;
       normalize();
   }

   // currency whole units mutator
   void setWholePart(int wPart)
   {
       wholePart = wPart;
   }
   // currency fractional units mutator
   void setFractionalPart(int fPart)
   {
       fractionalPart = fPart;
       normalize();
   }

   // currency whole units accessor
   int getWholePart() const
   {
       return wholePart;
   }
   // currency whole units accessor
   int getFractionalPart() const
   {
       return fractionalPart;
   }

   // Overloaded operator functions

   //**********************************************************************//
   // Currency operator + //
   // pre: currency object we want to add. //
   // return: sum of the operands //
   //**********************************************************************//
   Currency operator + (const Currency &); // Overloaded +

   //**********************************************************************//
   // Currency operator - //
   // pre: currency objects we want to subtract. //
   // return: result of subtration the operands //
   //**********************************************************************//
   Currency operator - (const Currency &); // Overloaded -

   //**********************************************************************//
   // Currency operator > //
   // pre: currency objects we want to compare. //
   // return: result of comparing the operands (>) //
   //**********************************************************************//
   virtual bool operator > (const Currency &);       // Overloaded >

   //**********************************************************************//
   // Currency operator < //
   // pre: currency objects we want to compare. //
   // return: result of comparing the operands (<) //
   //**********************************************************************//
   virtual bool operator < (const Currency &);       // Overloaded <

   //**********************************************************************//
   // Currency operator == //
   // pre: currency objects we want to compare. //
   // return: result of comparing the operands (==) //
   //**********************************************************************//
   virtual bool operator == (const Currency &);   // Overloaded ==

   //**********************************************************************//
   // Currency operator = //
   // pre: source and target Currency opjects we want to perform a copy //
   // operation on. //
   // return: result of assign one operand the result of an RHS expression.//
   //**********************************************************************//
   virtual Currency& operator=(const Currency &); // overloaded =
};

Source code for SelectionSort.h:

#pragma once

//**********************************************************************//
// Template for Selection Sort utilty function //
//**********************************************************************//
#include "ArrayTemplateClass.h"
#include "Dollar.h"

// The templated predecessor operator (>)
// Predecessor for generic items
template<typename T>
bool pred(T& Lhs, T& Rhs) {
   return Lhs > Rhs;
}

//**********************************************************************//
// Swap Template //
// pre: Left and Right hand operator                                   //
// post: Swapped values for left and right hand operator           //
// return: void                                                           //
//**********************************************************************//
template<typename T>
void swapit(T& L, T& R) {
   T tmp = L;
   L = R;
   R = tmp;
}


//**********************************************************************//
// recurSelectionSort Template - This template allows sorting of       //
//   integral types, system library types, and user defined objects.       //
//                                                                       //
// pre: Unordered item list                                               //
// post: Ordered item list in descending order                           //
// return: void                                                           //
//**********************************************************************//
template<typename T>
void recurSelectionSort(Array<T>& ArrayToSort, int ArraySize, int PartitionIndex = 0) {
   ofstream exelog;
   exelog.open("Log.txt", ios::app);

   if (PartitionIndex >= ArraySize)
       return; // Should be sorted.
   // Find min element
   T MinElem = ArrayToSort[PartitionIndex];

   int MinElemIdx = PartitionIndex;
   for (int ndx = PartitionIndex; ndx < ArraySize; ++ndx)
       if (pred(ArrayToSort[ndx], MinElem)) {
           MinElem = ArrayToSort[ndx];
           MinElemIdx = ndx;
       }
   // Found the minimum element. It's in MinElemIdx
   swapit(ArrayToSort[PartitionIndex], ArrayToSort[MinElemIdx]);


   for (int i = 0; i < ArraySize; i++)
   {
       cout << " " << ArrayToSort[i];
       exelog << " " << ArrayToSort[i];
   }
   cout << endl;
   exelog << endl;
   exelog.close();

   // Now everything until PartitionIndex is sorted. recurse on beyond the PartitionIndex
   recurSelectionSort(ArrayToSort, ArraySize, PartitionIndex + 1);
}

Source code for ArrayTemplateClass.h:

#pragma once
using namespace std;

template <typename T>
class Array
{
private:
   int m_nLength;
   T *m_ptData;

public:
   Array();

   Array(int nLength);

   ~Array();

   void Erase();

   //**********************************************************************//
   // Array operator [] - our Array subscript operator //
   // PRE : target index array request. //
   // RETURN : Reference of the Array object we are targeting. //
   //**********************************************************************//
   T& operator[](int &nIndex);

   // The length of the array is always an integer
   // It does not depend on the data type of the array
   int GetLength(); // templated GetLength() function defined below
};


// Constructor template no parameters. Initialises our member variables
template<typename T>
Array<T>::Array()
{
   m_nLength = 0;
   m_ptData = 0;
}

// Constructor template one parameter.
// Iniitialises our member variables setting the
// length parameter according to user specifications
template<typename T>
Array<T>::Array(int nLength)
{
   m_ptData = new T[nLength];
   m_nLength = nLength;
}

// Destructor template, We need to clean up after ourselves
template<typename T>
Array<T>::~Array()
{
   delete[] m_ptData;
}

// Erase utility function
template<typename T>
void Array<T>::Erase()
{
   delete[] m_ptData;
   // We need to make sure we set m_pnData to 0 here, otherwise it will
   // be left pointing at deallocated memory!
   m_ptData = 0;
   m_nLength = 0;
}


// Subscript overload operator for Array Template
template<typename T>
T & Array<T>::operator[](int & nIndex)
{
   if (nIndex >= 0 && nIndex < m_nLength)
       return m_ptData[nIndex];
   return m_ptData[0];
}

// Getlegth utility, returns GetLength
template <typename T>
int Array<T>::GetLength() { return m_nLength; }

Output Screenshots:

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.