Friday, March 30, 2018

Temporary Discontinuation

Dear readers, 

It has been another couple of days with complete silence since the last solution was published. This time it is not because of any particular problem related to any one Challenge, or that this person has given up learning and decided to do quietly move on.

It is due to unfortunate events in real-life, that there will be a discontinuation of this project for quite some time. Until then, there may or may not follow sporadic solutions, but it is impossible to promise this. The only thing that is certain and can be promised as of the time of writing this, that once things are back to normal, there will follow solutions in regular order, and this book will be finished as planned.

As sad as it is, but this will then be the last occassion for what this person normally enjoyed the most: To thank all visitors for the continuous interest, and my followers, whom I thank very much for subscribing. It is hoped that you will come by regularly to see whether there is any news and/or updates, and that this humble blog will remain or become a source of some little help to all those who seek it.

Regards,
Yuki

Thursday, March 22, 2018

Programming Challenge 17.3 - Capital Quiz

Example Files: CapitalQuiz.7z

Notice: The original Ascii-Art was taken from http://www.chris.com/ascii/joan/www.geocities.com/SoHo/7373/flag.html © by Joan G. Stark. http://www.ascii-art.com/

FileLoader.h


#ifndef FILE_LOADER_H_
#define FILE_LOADER_H_

#include <fstream>
#include <map>
#include <string>

class FileLoader
{
    private:
        std::string      fileName;
        std::ifstream flagFile;
        std::ifstream quizFile;

        std::map<std::string, std::string> quiz;
      
    public:
        FileLoader();

        bool loadHeader();
        bool loadQuiz();

        std::map<std::string, std::string> getQuiz()
        { return quiz; }
};

#endif

FileLoader.cpp


#include "FileLoader.h"

#include <iostream>
#include <string>

/* **********************************************************
            FileLoader::FileLoader() - Constructor
   ********************************************************** */

FileLoader::FileLoader()
{
    loadHeader();
    loadQuiz();
}

/* **********************************************************
            FileLoader::loadHeader()
    If the file is opened successfully, a header graphic is
    loaded and displayed. Otherwise the function exits with
    an error message.
   ********************************************************** */

bool FileLoader::loadHeader()
{
    bool status = true;

    flagFile.open("Flag.txt");

    if (flagFile.fail())
    {
        std::cout << "\nFile Open Error: Unable to load flag file.\n";
        std::cout << "Please exit this program and try again ..." << std::endl;
        status = false;
    }
    else
    {
        std::string output{};

        while (getline(flagFile, output))
        {
            std::cout << output << "\n";
        }
    }

    flagFile.close();
    return status;
}

/* **********************************************************
            FileLoader::loadQuiz()
    If loaded successfully, a key value pair is read in from
    the file and inserted into the map. Otherwise an error
    message is displayed and the function exits.
   ********************************************************** */

bool FileLoader::loadQuiz()
{
    bool status = true;
    quizFile.open("Capitals.txt");

    if (quizFile.fail())
    {
        std::cout << "\nFile Open Error: Unable to load " << fileName << " file.\n";
        std::cout << "Please exit this program and try again ..." << std::endl;
        status = false;
    }
    else
    {
        std::string firstVal{};
        std::string secondVal{};

        while (getline(quizFile, firstVal, ':') && getline(quizFile, secondVal))
        {
            std::map<std::string, std::string>::iterator it = quiz.begin();
            quiz.insert(it, std::pair<std::string, std::string>(firstVal, secondVal));
        }
    }

    quizFile.close();
    return status;
}

Capital.h


#ifndef CAPITAL_QUIZ_H_
#define CAPITAL_QUIZ_H_

#include "FileLoader.h"

#include <map>
#include <string>

class Capital
{
    private:       
        FileLoader  loader;
        static int    points;

        std::map<std::string, std::string> capitals;
        std::map<std::string, std::string>::iterator it;

    public:
        Capital()
        { capitals = loader.getQuiz(); }

        void presentQuestion();
        void getAnswer();
        void evaluateAnswer(std::string);
        void removeQuestion();

        int getMapSize() const
        { return capitals.size(); }

        int getPoints() const
        { return points; }

        bool operator < (const Capital &) const;
};

#endif

Capital.cpp


#include "Capital.h"

#include <algorithm>
#include <iostream>

int Capital::points = 0;

/* **********************************************************
            Capital::presentQuestion()
    This function selects a random question and outputs it to
    screen.
   ********************************************************** */

void Capital::presentQuestion()
{
    std::advance(it = capitals.begin(), rand() % capitals.size());
    std::cout << "\nWhat is the capital of " << it->first << "?\n";
}

/* **********************************************************
            Capital::getAnswer()
    The user is asked to enter his or her answer. The answer
    is evaluated by call to the appropriate function.
   ********************************************************** */

void Capital::getAnswer()
{
    std::string answer{};

    std::cout << "Your answer: ";
    getline(std::cin, answer);

    evaluateAnswer(answer);
}

/* **********************************************************
            Capital::evaluateAnswer() : std::string
    This function evaluates the answer passed to it by value.
    If it is correct, 5 points are assigned to the player's
    score, and the question is removed from the map. Otherwise
    a point is deducted, iff the score is greater 0, and the
    question remains in the queue.
   ********************************************************** */

void Capital::evaluateAnswer(std::string answer)
{
    if (it->second == answer)
    {
        std::cout << "\nCorrect (^-^)\n";
        points += 5;
        removeQuestion();
    }
    else
    {
        std::cout << "\nWrong (;-;)\n";
        std::cout << "The capital of " << it->first << " is " << it->second << "\n\n";

        points > 0 ? points -= 1 : points = 0;
    }
}

/* **********************************************************
            Capital::removeQuestion()
    Erases a key value pair from the map.
   ********************************************************** */

void Capital::removeQuestion()
{
    if (capitals.size() > 0)
    {
        capitals.erase(it);
    }
}

/* **********************************************************
            Overloaded < operator   
   ********************************************************** */

bool Capital::operator < (const Capital &right) const
{
    bool status = false;

    if (capitals < right.capitals)
    {
        status = true;
    }
    return status;
}

CapitalQuiz.cpp


#include "Capital.h"

#include <iostream>
#include <ctime>

int main()
{
    Capital capitalQuiz;

    char choice{};

    srand((unsigned int)time(NULL));

    do
    {
        capitalQuiz.presentQuestion();
        capitalQuiz.getAnswer();

        if (capitalQuiz.getMapSize() > 0)
        {
            std::cout << "Do you wish to continue? (y/N): ";
            std::cin >> choice;
            std::cin.ignore();

            while (toupper(choice) != 'Y' && toupper(choice) != 'N')
            {
                std::cin.sync();
                std::cout << "Do you wish to continue? (y/N): ";
                std::cin >> choice;
                std::cin.ignore();
            }

            if (toupper(choice) == 'N')
            {
                std::cout << "\nWell Done! You earned " << capitalQuiz.getPoints() << " points!\n";
                std::cout << "Thank you for playing this quiz!" << std::endl;           
            }
        }
        else
        {
            std::cout << "\nWell Done! You answered all questions and earned: "
                         << capitalQuiz.getPoints() << " points!\n";
            std::cout << "Thank you for playing this quiz!" << std::endl;
        }
    } while (toupper(choice) != 'N' && capitalQuiz.getMapSize() > 0);

    std::cin.ignore();
    return 0;
}

Example Output:




Tuesday, March 20, 2018

Programming Challenge 17.2 - Course Information

Example Files: CourseInformation.7z

CourseInformation.cpp


#include <iomanip>
#include <iostream>
#include <map>
#include <string>

void courseSearch(const std::map<std::string, std::string> &,
                        const std::map<std::string, std::string> &,
                        const std::map<std::string, std::string> &);

void print(const std::map<std::string, std::string>::const_iterator,
                      std::map<std::string, std::string>,
                      std::map<std::string, std::string>);

int main()
{
    std::map<std::string, std::string> rooms =
    { { "CS101", "3004" }, { "CS102", "4501" }, { "CS103", "6755" },
      { "NT110", "1244" }, { "CM241", "1411" } };

    std::map<std::string, std::string> instructors =
    { { "CS101", "Haynes" }, { "CS102", "Alvarado" }, { "CS103", "Rich" },
      { "NT110", "Burke" }, { "CM241", "Lee" } };

    std::map<std::string, std::string> timetables =
    { { "CS101", "08:00 a.m." }, { "CS102", "09:00 a.m." }, { "CS103", "10:00 a.m." },
      { "NT110", "11:00 a.m" }, { "CM241", "01:00 p.m." } };

    char again{};

    std::cout << "M.I.T. COMPUTER SCIENCE DEPARTMENT COURSE SEARCH\n";

    do
    {
        courseSearch(rooms, instructors, timetables);

        std::cout << "\nDo you wish to repeat your search? (Y/N): ";
        std::cin >> again;

        while (toupper(again) != 'Y' && toupper(again) != 'N')
        {
            std::cout << "\nPlease repeat your input: ";
            std::cin >> again;
        }
    } while (toupper(again) != 'N');

    std::cout << "\nM.I.T. - The Union Of Knowledge And Mechanical Arts.";

    std::cin.ignore();
    std::cin.ignore();
    return 0;
}

/* **********************************************************
            courseSearch() : const map &, const map &,
                                  const map &
    The user is asked to enter a course number. If it exists
    in the map, it will be output. Otherwise the user is
    informed, that the course does not exist.
   ********************************************************** */

void courseSearch(const std::map<std::string, std::string> &rooms,
                       const std::map<std::string, std::string> &instructors,
                       const std::map<std::string, std::string> &timetables)
{
    std::string courseID{};

    std::cout << "\nEnter a course ID: ";
    std::cin >> courseID;

    std::map<std::string, std::string>::const_iterator it = rooms.find(courseID);

    if (it != rooms.end())
    {
        print(it, instructors, timetables);
    }
    else
    {
        std::cout << courseID << " does not exist ..." << std::endl;
    }
}

/* **********************************************************
            print() : const map<>::iterator, map, map
    The user is asked to enter a course number. If it exists
    in the map, it will be output. Otherwise the user is
    informed, that the course does not exist.
   ********************************************************** */

void print(const std::map<std::string, std::string>::const_iterator it,
                      std::map<std::string, std::string> instructors,
                      std::map<std::string, std::string> timetables)
{
    std::cout << "\n" << std::setw(15) << std::left << "Course:"
                            << std::setw(12) << std::left << "Room:"
                            << std::setw(23) << std::left << "Instructor:"
                            << std::setw(5) << std::left << "Time:\n";
   
    std::cout << std::setw(14) << std::left
                 << std::setw(15) << std::left << it->first
                 << std::setw(12) << std::left << it->second
                 << std::setw(23) << std::left << instructors[it->first]
                 << std::setw(18) << std::left << timetables[it->first] << std::endl;
}

Example Output:



Sunday, March 18, 2018

Programming Challenge 17.1 - Unique Words

Example Files: UniqueWords.7z
                           short.txt
                           night.txt

UniqueWords.cpp


#include <algorithm>
#include <cctype>
#include <iostream>
#include <iterator>
#include <fstream>
#include <set>
#include <string>

bool createList(const std::string, std::set<std::string> &);
void printList(const std::set<std::string> &);

int main()
{
    std::string                 filename{};
    std::set<std::string> uniqueWords{};

    std::cout << "UNIQUE WORDS\n\n";
    std::cout << "This program lets you create and display list of unique words\n";
    std::cout << "from a text stored in a file.\n\n";
    std::cout << "Enter the name of the file you wish to open:\n";

    getline(std::cin, filename);

    if (createList(filename, uniqueWords))
    {
        printList(uniqueWords);
        std::cout << "\nThank you for trying this program! Have a nice day!" << std::endl;
    }

    std::cin.ignore();
    return 0;
}

/* **********************************************************
            bool createList() : const string, std::set<string>
    This function reads in words from a file into a set.
   ********************************************************** */

bool createList(const std::string filename, std::set<std::string> &temp)
{
    std::string     word{};
    std::fstream inFile{};
    bool         status{};
   
    inFile.open(filename, std::ios::in);
   
    if (inFile)
    {
        while (inFile >> word)
        {
            transform(word.begin(), word.end(), word.begin(), ::tolower);
            word.erase(remove_if(word.begin(), word.end(), ::ispunct), word.end());

            temp.insert(word);
        }   
        status = true;
    }
    else
    {
        std::cout << "\nFile open error ...\n";
        std::cout << "Please close this program and try again." << std::endl;

        status = false;
    }
    inFile.close();
   
    return status;
}

/* **********************************************************
            printList() : const std::set<string>
    Outputs the list of unique words.
   ********************************************************** */

void printList(const std::set<std::string> &words)
{
    std::cout << "\nUNIQUE WORDS:\n";
    for (auto printWords : words)
    {
        std::cout << printWords << "\n";
    }
}

Example Output:




Monday, March 12, 2018

Another Update



It is no shame to admit that this person is currently unable to make significant progress in solving Programming Challenge 16.12. As there is no way of telling how much longer it will take a decision had to be made. Instead of investing all energy into this one project, while there are still five chapters left to work through and many more Challenges waiting to be solved, this person has decided to continue on to the next chapter for now. 

Numerous possibilites were taken into consideration to determine what happens with Programming Challenge 16.12 in the meantime. For now the work on it will continue on the side. If it isn't taking away time and energy from the learning process, it will be kept up, until the problem is solved. Otherwise it will have to wait until the end of the book has been reached. This is for the reason that, since the newest revision of this book has some additional Programming Challenges in earlier chapters, solutions for these Challenges may also find their way to this blog. It is some additional exercise, so it would fit in well to come back to this as yet unsolved Challenge by that time.

For now, it is time to keep on learning, to make some progress, and to hopefully be able to finish this one Challenge soon. As always it is a pleasure to thank all visitors for the continued interest in this person's humble blog, a special pleasure to thank my followers for subscribing! To my fellow students, who may not have the luxury to move on, for whom there are grades at stake if they do not manage to solve a problem in time, don't despair and keep giving your best. When you are ready, get back to it and work on a solution in your own time, then solve it. Persistence is key!

Wednesday, March 7, 2018

Update

Dear readers, you may have noticed that there is a gap in numbers in between Programming Challenges 16.11 and 16.13. The reason is not that this person has skipped Challenge 16.12, quite the contrary. It is a very difficult challenge, thus it will take some more time to arrive at a solution, so instead this person decided to solve what felt to be a very easy last challenge of this chapter, then return to work on the more difficult one. This person will work hard to get it done soon, so as to be able to continue on to Chapter 17.

With this little update information out of the way, it is time for this person to take a small break to gather new mental energy, to finally also get done with Challenge 16.12. In the meantime I wish my readers, visitors old and new, and my fellow students all the best in their attempt to solve any problem however difficult it may seem! Give your best!

Programming Challenge 16.13 - Exceptions Project

Example Files: ExceptionsProject.7z

Employee.h


#ifndef EMPLOYEE_H_
#define EMPLOYEE_H_

#include <iostream>
#include <string>

class Employee
{
    private:
        int            employeeID;
        std::string employeeName;
        std::string employeeHireDate;

    public:
        class InvalidEmployeeID
        {
            private:   
                int invalidEmployeeID;

            public:
                InvalidEmployeeID(int invalidEmpID) : invalidEmployeeID(invalidEmpID)
                { }

                int getInvalidEmployeeID() const
                { return invalidEmployeeID; }
        };

        Employee(int, std::string, std::string);
        virtual ~Employee()
        { }

        // Mutator function
        void setEmployee(int, std::string, std::string);

        // Accessor function
        void invalidIDHandler() const;

        // Consider directly employing the overloaded operator and call it from the
        // Production worker class
        friend std::ostream &operator << (std::ostream &, const Employee &);
       
        virtual void print(std::ostream &) const;
};

#endif

Employee.cpp


#include "Employee.h"

#include <iomanip>

/* **********************************************************
            Employee::Employee() : int, string, string
            - Constructor
   ********************************************************** */

Employee::Employee(int empID, std::string empName, std::string empHired) :
    employeeID(empID), employeeName(empName), employeeHireDate(empHired)
{
    invalidIDHandler();
}

/* **********************************************************
            Employee::setEmployee() : int, string, string
    Sets the employee data.
   ********************************************************** */

void Employee::setEmployee(int empID, std::string empName, std::string empHired)
{
    employeeID = empID;
    employeeName = empName;
    employeeHireDate = empHired;

    invalidIDHandler();
}

/* **********************************************************
            Employee::invalidIDHandler()
    Evaluates the employeeID and throws an exception if found
    invalid.
   ********************************************************** */

void Employee::invalidIDHandler() const
{
    if (employeeID < 0 || employeeID > 9999)
    {
        throw InvalidEmployeeID(employeeID);
    }
}

/* **********************************************************
            Overloaded << function
   ********************************************************** */

std::ostream &operator << (std::ostream &strm, const Employee &obj)
{
    obj.print(strm);
    return strm;
}

/* **********************************************************
            Employee::print() : ostream &
    Outputs the employee data to screen.
   ********************************************************** */

void Employee::print(std::ostream &strm) const
{
    strm << std::left  << std::setw(12) << "Employee Name: "
          << std::right << employeeName << std::endl;
    strm << std::left << std::setw(15) << "Employee ID: "
          << std::right << employeeID << std::endl;
    strm << std::left  << std::setw(15) << "Hire Date: "
          << std::right << employeeHireDate << std::endl << std::endl;
}

ProductionWorker.h


#ifndef PRODUCTION_WORKER_H_
#define PRODUCTION_WORKER_H_

#include "Employee.h"

#include <iostream>
#include <string>

class ProductionWorker : public Employee
{
    private:
        int     shiftNumber;
        double hourlyPayrate;

    public:
        class InvalidPayrate
        {
            private:
                double invalidPayrate;

            public:
                InvalidPayrate(double invalidRate) : invalidPayrate(invalidRate)
                { }

                double getInvalidPayrate() const
                { return invalidPayrate; };
        };

        class InvalidShiftData
        {
            private:
                int invalidShiftID;

            public:
                InvalidShiftData(int invalidShift) : invalidShiftID(invalidShift)
                { }

                int getInvalidShiftID() const
                { return invalidShiftID; }
        };

        ProductionWorker(int, std::string, std::string, int, double);

        void setProductionWorker(int, double);

        void invalidShiftHandler() const;
        void invalidPayrateHandler() const;

        void print(std::ostream &) const override;
};

#endif

ProductionWorker.cpp


#include "ProductionWorker.h"

#include <iomanip>

/* **********************************************************
            ProductionWorker::ProductionWorker() : int, string,
            string, int, double - Constructor
   ********************************************************** */

ProductionWorker::ProductionWorker(int empID, std::string empName, std::string empHired,
                                              int shiftID, double payRate) :
                                              shiftNumber(shiftID),hourlyPayrate(payRate),
                                              Employee(empID, empName, empHired)
{
    invalidShiftHandler();
    invalidPayrateHandler();
}

/* **********************************************************
            ProductionWorker::setProductionWorker() int, double
    Sets the production worker data.
   ********************************************************** */

void ProductionWorker::setProductionWorker(int shiftID, double payRate)
{
    shiftNumber = shiftID;
    hourlyPayrate = payRate;

    invalidShiftHandler();
    invalidPayrateHandler();
}

/* **********************************************************
            ProductionWorker::shiftErrorHandler()
    Evaluates the shiftNumber and throws an exception if found
    invalid.
   ********************************************************** */

void ProductionWorker::invalidShiftHandler() const
{
    if (shiftNumber < 0 || shiftNumber > 2)
    {
        throw InvalidShiftData(shiftNumber);
    }
}

/* **********************************************************
            ProductionWorker::payRateErrorHandler()
    Evaluates the hourlyPayRate and throws an exception if
    found invalid.
   ********************************************************** */

void ProductionWorker::invalidPayrateHandler() const
{
    if (hourlyPayrate < 0.0)
    {
        throw InvalidPayrate(hourlyPayrate);
    }
}

/* **********************************************************
            ProductionWorker::print() : ostream &
    Outputs the production worker data to screen.
   ********************************************************** */

void ProductionWorker::print(std::ostream &strm) const
{
    Employee::print(strm);

    strm << "Shift #" << shiftNumber << ": ";

    shiftNumber == 1 ?
        strm << std::setw(16) << std::right << "Day-Shift"   << std::endl :
        strm << std::setw(16) << std::right << "Night-Shift" << std::endl;

    strm << std::fixed << std::setprecision(2) << std::fixed;
    strm << std::left  << std::setw(14) << "Pay Rate: "
          << std::right << "$ " << hourlyPayrate << std::endl;
}

ExceptionProject.cpp


#include "ProductionWorker.h"

#include <iostream>

void badValueCheck(int, std::string, std::string, int, double);

int main()
{
    std::cout << "TAKEUCHI MANUFACTURING CO. - EMPLOYEE DATA VALIDATION\n\n";
    std::cout << "The following tests will now be carried out:\n\n";

    std::cout << "Test 1: Employee Number\n";
    badValueCheck(99921, "Flanders Moll", "17/04/2013", 2, 86.80);
    std::cout << std::endl;

    std::cout << "Test 2: Shift ID\n";
    badValueCheck(1241, " Kakuta", "12/03/2015", -7, 85.99);
    std::cout << std::endl;

    std::cout << "Test 3: Hourly Payrate\n";
    badValueCheck(9411, "Vishneva Diana", "12/03/2015", 1, -190.55);
    std::cout << std::endl;

    std::cout << "Test 4: Correct Data\n";
    badValueCheck(4350, "Hiroshi Sato", "15/05/2005", 2, 99.75);
    std::cout << std::endl;

    std::cout << "You are now leaving the Database System ...\n\n";
    std::cout << "TAKEUCHI MANUFACTURING CO.\n"
             << "Unrivaled quality, products with a difference,\n"
             << "and fast development responding to the users' needs.";

    std::cin.get();
    return 0;
}

/* **********************************************************
            badValueCheck() : int, string, string, int, double
    This function tests various data items for validity. If an
    item is invalid, it is caught, and an error message is
    output. Otherwise the production worker data is output.
   ********************************************************** */

void badValueCheck(int empID, std::string empName, std::string empHired,
                         int shiftID, double payRate)
{
    try
    {
        ProductionWorker temp(empID, empName, empHired, shiftID, payRate);

        std::cout << temp;
    }
    catch (ProductionWorker::InvalidEmployeeID badEmployeeID)
    {
        std::cout << "Error! Invalid Employee ID: "
                     << badEmployeeID.getInvalidEmployeeID() << std::endl;
    }
    catch (ProductionWorker::InvalidShiftData badShiftID)
    {
        std::cout << "Error! Invalid Shift ID: "
                     << badShiftID.getInvalidShiftID() << std::endl;
    }
    catch (ProductionWorker::InvalidPayrate badPayrate)
    {
        std::cout << "Error! Invalid Hourly Payrate: $ "
                     << badPayrate.getInvalidPayrate() << std::endl;
    }
}

Example Output:



Monday, February 26, 2018

Programming Challenge 16.11 - Inheritance Modification

Example Files: InheritanceModification.7z

Notice: The only file that has directly changed is the SearchableVector class. The other files remain the same, and are to be found in the Example Files archive, but are not republished here.

SearchableVector.h


#ifndef SEARCHABLE_VECTOR_H_
#define SEARCHABLE_VECTOR_H_

#include "SortableVector.h"

template <class T>
class SearchableVector : public SortableVector<T>
{
    public:
        // Constructors
        SearchableVector() : SortableVector<T>()
        { }

        SearchableVector(int size) : SortableVector<T>(size)
        { }

        SearchableVector(const SearchableVector &);
   
        // Accessor function
        void findItem(const T &);
        int sortAndSearch(const T &);
};

/* **********************************************************
            SearchableVector<T>::SearchableVector()
         - Copy Constructor
   ********************************************************** */

template <class T>
SearchableVector<T>::SearchableVector(const SearchableVector &obj) :
                           SortableVector<T>(obj)
{
}

/* **********************************************************
            SearchableVector<T>::findItem() : const T &
    This function passes the value to search for in a given
    array to the sortAndSearch function. If the value exists,
    it is output. Otherwise a message indicating that the
    value does not exist is output.
   ********************************************************** */

template<class T>
void SearchableVector<T>::findItem(const T &val)
{
    int result = 0;

    result = this->sortAndSearch(val);

    if (result == -1)
    {
        cout << val << " does not exist ...\n\n";
    }
    else
    {
        cout << val << " was found at subscript position "
              << result << "\n\n";
    }
}

/* **********************************************************
            SearchableVector<T>::sortAndSearch() const T &
    This function first sorts an array, by calling the
    SortableVector class's sortItems() function, then a binary
    search algorithm is used, to find a value in it. If the
    value is found, the position is returned. Otherwise -1 is
    returned.
    ********************************************************** */

template <class T>
int SearchableVector<T>::sortAndSearch(const T &item)
{
    SortableVector<T>::sortItems();
   
    int  firstElem = 0;
    int  midPoint = 0;
    int  lastElem = SimpleVector<T>::getArraySize() - 1;
    int  position = -1;
    bool status = false;

    while (status == false && firstElem <= lastElem)
    {
        midPoint = (firstElem + lastElem) / 2;

        if (SimpleVector<T>::operator[](midPoint) == item)
        {
            position = midPoint;
            status = true;
        }

        SimpleVector<T>::operator[](midPoint) > item ? lastElem = midPoint - 1 :
                                                                 firstElem = midPoint + 1;
    }

    return position;
}

#endif

InheritanceMod.cpp


#include "SearchableVector.h"

#include <cstdlib>
#include <ctime>

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

#include <string>
using std::string;

/* **********************************************************
            print() : const <T> &obj, const string
    Outputs the object's current contents to screen.
    ********************************************************** */

template <class T>
void print(const SearchableVector<T> &obj, const string objName)
{
    cout << "These values are currently in your " << objName << ":\n";
    cout << obj << "\n\n";
}

/* **********************************************************
                                        main()
   ********************************************************** */

int main()
{
    const int    SIZE = 16;
    const string objNames[] = { "intTable", "doubleTable", "charTable" };

    srand(static_cast<unsigned int> (time(0)));

    SearchableVector<int>    intTable(SIZE);
    SearchableVector<double> doubleTable(SIZE);
    SearchableVector<char>   charTable(SIZE);

    cout << "SORTABLE AND SEARCHABLE VECTOR DEMO\n\n";
    cout << "Now filling the arrays with random values ...\n\n";
    for (int count = 0; count < SIZE; count++)
    {
        intTable[count] = rand() % SIZE + (count * 2);
        doubleTable[count] = rand() % SIZE * (count * 2.2);
        charTable[count] = rand() % SIZE - 191;
    }

    print(intTable, objNames[0]);
    print(doubleTable, objNames[1]);
    print(charTable, objNames[2]);

    cout << "Now sorting and searching for values in the arrays:\n\n";
    intTable.findItem(22);
    doubleTable.findItem(132.0);
    charTable.findItem('I');

    cout << "These are the items now in sorted order:\n\n";
    print(intTable, objNames[0]);
    print(doubleTable, objNames[1]);
    print(charTable, objNames[2]);

    cout << "Thank you for trying this program! Have a nice day!";
    cin.get();
   return 0;
}

Example Output:





Programming Challenge 16.10 - SortableVector Class Template

Example Files: SortableVectorClassTemplate.7z

SortableVector.h


#ifndef SORTABLE_VECTOR_H_
#define SORTABLE_VECTOR_H_

#include "SimpleVector.h"

template <class T>
class SortableVector : public SimpleVector<T>
{
    public:
        SortableVector() : SimpleVector<T>()
        { }

        SortableVector(int size) : SimpleVector<T>(size)
        { }

        SortableVector(const SortableVector &);

        // Mutator function
        void sortItems();
};

/* **********************************************************
            SortableVector<T>::SortableVector()
         - Copy Constructor
   ********************************************************** */

template <class T>
SortableVector<T>::SortableVector(const SortableVector &obj) :
                      SimpleVector<T>(obj.getArraySize())
{
    for (int count = 0; count < this->getArraySize(); count++)
    {
        this->operator[](count) = obj[count];
    }
}

/* **********************************************************
            SortableVector<T>::sortItems() : const T &
   This function uses a selection sort algorithm to sort the
    array's elements in ascending order.
   ********************************************************** */

template <class T>
void SortableVector<T>::sortItems()
{
    int startScan = 0;
    int index = 0;
    int minIndex = 0;
    T minValue{};

    for (; startScan < this->getArraySize() - 1; startScan++)
    {
        minIndex = startScan;
        minValue = this->operator[](startScan);

        for (index = startScan + 1; index < this->getArraySize(); index++)
        {
            if (this->operator[](index) < minValue)
            {
                minValue = this->operator[](index);
                minIndex = index;
            }
        }

        this->operator[](minIndex) = this->operator[](startScan);
        this->operator[](startScan) = minValue;
    }
}

#endif

SortableVectorDm.cpp


#include "SortableVector.h"

#include <cstdlib>
#include <ctime>

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

#include <string>
using std::string;

/* **********************************************************
            print() : const <T> &obj, const string
    Outputs the object's current contents to screen.
    ********************************************************** */

template <class T>
void print(const SortableVector<T> &obj, const string objName)
{
    cout << "These values are currently in your " << objName << ":\n";
    cout << obj << "\n\n";
}

/* **********************************************************
                                        main()
   ********************************************************** */

int main()
{
    const int    SIZE = 16;
    const string objNames[] = { "intTable", "doubleTable", "charTable" };

    srand(static_cast<unsigned int> (time(0)));

    SortableVector<int>    intTable(SIZE);
    SortableVector<double> doubleTable(SIZE);
    SortableVector<char>   charTable(SIZE);

    cout << "SORTABLE VECTOR DEMO\n\n";
    cout << "Now filling the arrays with random values ...\n";
    for (int count = 0; count < SIZE; count++)
    {
        intTable[count] = rand() % SIZE * 1 + (4 * 2);
        doubleTable[count] = rand() % SIZE * (count + (4 * 3.44));
        charTable[count] = rand() % SIZE - 191;
    }

    print(intTable, objNames[0]);
    print(doubleTable, objNames[1]);
    print(charTable, objNames[2]);

    cout << "Now sorting the items ...\n\n";
    intTable.sortItems();
    doubleTable.sortItems();
    charTable.sortItems();
   
    print(intTable, objNames[0]);
    print(doubleTable, objNames[1]);
    print(charTable, objNames[2]);

    cout << "Thank you for trying this program! Have a nice day!";
    cin.get();
   return 0;
}

ExampleOutput:



Sunday, February 25, 2018

Programming Challenge 16.9 - SearchableVector Modification

Example Files: SearchableVectorModification.7z

Notice: Since no changes have been made to the SimpleVector class, it is included in the Example Files archive, but not republished here. Most of the code for this project is taken from pp. 1020 through 1022 in the 9th Edition, or 1002 through 1004 in the 8th Edition of this book.

SearchableVector.h


#ifndef SEARCHABLE_VECTOR_H_
#define SEARCHABLE_VECTOR_H_

#include "SimpleVector.h"

template <class T>
class SearchableVector : public SimpleVector<T>
{
    public:
        // Constructors
        SearchableVector() : SimpleVector<T>()
        { }

        SearchableVector(int size) : SimpleVector<T>(size)
        { }

        SearchableVector(const SearchableVector &);

        // Accessor function
        int findItem(const T &);
};

/* **********************************************************
            SearchableVector<T>::SearchableVector()
         - Copy Constructor
   ********************************************************** */

template <class T>
SearchableVector<T>::SearchableVector(const SearchableVector &obj) :
                             SimpleVector<T>(obj.getArraySize())
{
    for (int count = 0; count < this->getArraySize(); count++)
    {
        this->operator[](count) = obj[count];
    }
}

/* **********************************************************
            SearchableVector<T>::findItem() : const T
    This function uses a binary search algorithm to find an
    item. If the item is found the subscript is returned.
    Otherwise -1 is returned.
   ********************************************************** */

template <class T>
int SearchableVector<T>::findItem(const T &item)
{
    int  firstElem = 0;
    int  midPoint = 0;
    int  lastElem = this->getArraySize() - 1;
    int  position = -1;
    bool status = false;

    while (status == false && firstElem <= lastElem)
    {
        midPoint = (firstElem + lastElem) / 2;

        if (this->operator[](midPoint) == item)
        {
            position = midPoint;
           status = true;
        }
       
        this->operator[](midPoint) > item ? lastElem = midPoint - 1 :
                                                        firstElem = midPoint + 1;
    }

    return position;
}

#endif

SearchableVectorMod.cpp


#include "SearchableVector.h"

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

#include <string>
using std::string;


/* **********************************************************
            findVal() : const <T> &obj, const T &, const string
    This function searches for a value in the object's array.
    If -1 is returned from the findItem() function, a message
    is output to indicate the fact that the value does not
    exist. Otherwise the value and subscript it was found at
    is output.
   ********************************************************** */

template <class T>
void findVal(SearchableVector<T> &obj, const T &val)
{
    int result = 0;

    result = obj.findItem(val);

    if (result == -1)
    {
        cout << val << " does not exist ...\n\n";
    }
    else
    {
        cout << val << " was found at subscript position "
              << result << "\n\n";
    }
}

/* **********************************************************
            print() : const <T> &obj, const string
    Outputs the object's current contents to screen.
    ********************************************************** */

template <class T>
void print(const SearchableVector<T> &obj, const string objName)
{
    cout << "These values are currently in your " << objName << ":\n";
    cout << obj << "\n\n";
}

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

void printIntro();
void printOptions(const string *);

/* **********************************************************
                                        main()
   ********************************************************** */

int main()
{
    const int SIZE = 12;
    int       intVal = 0;
    int       choice = ' ';
    double    doubleVal = 0.0;
    char      charVal = ' ';
   
    const enum   options { INT = 1, DOUBLE = 2, CHAR = 3, PRINT = 4, QUIT = 5 };
    const string objNames[] = { "intTable", "doubleTable", "charTable" };

    SearchableVector<int>     intTable(SIZE);
    SearchableVector<double> doubleTable(SIZE);
    SearchableVector<char>   charTable(SIZE);

    printIntro();

    for (int count = 0; count < SIZE; count++)
    {
        intTable[count] = (count * 2);
        doubleTable[count] = (count * 2.14);
        charTable[count] = ((char)count - 191);  
    }

    do
    {
        printOptions(objNames);
        cout << "Choice: ";
        cin >> choice;

        while (choice < INT || choice > QUIT)
        {
            cout << "Choice: ";
            cin >> choice;
        }
        cout << "\n";

        switch (choice)
        {
            case INT:
            {
                cout << "Enter an integer value to search for: ";
                cin >> intVal;

                findVal(intTable, intVal);
            } break;

            case DOUBLE:
            {
                cout << "Enter an floating-point value to search for: ";
                cin >> doubleVal;

                findVal(doubleTable, doubleVal);
            } break;

            case CHAR:
            {
                cout << "Enter a character to search for: ";
                cin >> charVal;

                findVal(charTable, charVal);
            } break;

            case PRINT:
            {
                print(intTable, objNames[0]);
                print(doubleTable, objNames[1]);
                print(charTable, objNames[2]);
            } break;

            case QUIT:
            {
                cout << "Thank you for trying this program! Have a nice day!";
            } break;
        }
    } while (choice != QUIT);

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

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

void printIntro()
{
    cout << "SEARCHABLE VECTOR DEMO\n\n";
    cout << "This program let's you search for a value in an integer,\n"
           << "a floating-point, and a character array.\n\n";
    cout << "If the value exists, it will be output to screen. Otherwise\n"
          << "you will see a message telling you that the value does not exist.\n";
    cout << "You can repeat a search as many times as you wish to, or you\n"
          << "can quit the program and try again another time.\n\n";
}

/* **********************************************************
            printOptions() : const string *
    Outputs the available menu options.
   ********************************************************** */

void printOptions(const string *objNames)
{
    cout << "SEARCH TABLE:\n\n";
    cout << "1) " << objNames[0] << "\n";
    cout << "2) " << objNames[1] << "\n";
    cout << "3) " << objNames[2] << "\n";
    cout << "4) " << "Print Values\n";
    cout << "5) Quit\n\n";
}

Example Output:






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: