Tuesday, April 11, 2017

Programming Challenge 10.3 - Word Counter

/* Word Counter - This program contains a function that accepts a
   pointer to a C-string as an argument, that returns the number
   of words contained in the string. For instance, if the string
   argument is "Four score and seven years ago" the function returns
   the number 6.
  
   The program asks the user to input a string and then passes it to
   the function. The number of words in the string is displayed on
   the screen.
  
   Optional Exercise: This program also contains an overloaded version
   of this function that accepts a string class object as its argument. */

#include "Utility.h"

/* Counts the words contained in the string, returns the number of words*/
int countWords(char *);

/* Overloaded function: Counts words in the string class object, returns
the number of words */
int countWords(string);

int main()
{
   const int NUM_WORDS = 501;
   int         numWords = 0;
   char         sentence[NUM_WORDS];
   string     ctrlSentence = " ";

   cout << "\n\t\tWORD COUNT\n\n"
        << "\tEnter a sentence, " << (NUM_WORDS - 1)
        << " characters in length:\n\t";
   cin.getline(sentence, NUM_WORDS);

   cout << "\n\tYour sentence contains: " << (numWords = countWords(sentence))
      << " words.\n";

   cout << "\n\tEnter another sentence:\n\t";
   getline(cin, ctrlSentence);

   cout << "\n\tThis sentence contains: " << (numWords = countWords(ctrlSentence))
      << " words.\n";

   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: countWords

   This function accepts a pointer to a C-string as argument.
   It counts the words contained in the sentence passed to
   the function and returns this number.
   ********************************************************** */

int countWords(char *wordPtr)
{
   int  wordCount = 0;
   char delimList[] = "\" ´-.()*=_!?~<<>>:,\t\n";
   char *next_word = NULL;

   wordPtr = strtok_s(wordPtr, delimList, &next_word);

   while (wordPtr != NULL)
   {
      if (wordPtr != NULL)
      {
         wordPtr = strtok_s(NULL, delimList, &next_word);

         ++wordCount;
      }
   }

   return wordCount;
}

/* **********************************************************
   Definition: countWords

   This overloaded version of the function countWords accepts
   a string class object as argument. It counts the words in
   the string and returns the count.
   ********************************************************** */

int countWords(string ctrlString)
{
   size_t wordCount = 0,
          numDelims = 0;

   bool isDelim = true;

   for (size_t index = 0; index < ctrlString.length(); ++index)
   {
      /* If a delimiter or whitespace is found, numDelim increments,
         and isDelim(iter) gets true. Else a word is found, and
         wordCount increments. */
      if (isspace(ctrlString[index]) || ispunct(ctrlString[index]))
      {
        numDelims++;
           isDelim = true;
      }
      else if (isDelim && !ispunct(ctrlString[index + 1]))
      {
         isDelim = false;
         ++wordCount;
      }
   }

   return wordCount;
}

Example Output:






Thursday, April 6, 2017

Programming Challenge 10.2 - Backward String

/* Backward String - This program contains a funtion that accepts a
   pointer to a C-string as an argument. It displays the contents
   backward. For instance, if the string argument is "Gravity", the
   function displays "ytivarG". This function is demonstrated by
   asking the user to input a string that is passed to the function. */

#include "Utility.h"

/* Reverses a string entered by the user and displays it */
void reverseString(char *);

int main()
{
   const int NUM_CHARS = 51;

   /* Array to hold the word(s) */
   char *word = new char[NUM_CHARS]();

   char again = ' ';

   do
   {
      cout << "\n\tBACKWARD STRING - GNIRTS DRAWKCAB\n\n"
           << "\tEnter a word of up to " << (NUM_CHARS - 1)
           << " characters and I will reverse it: ";
      cin.getline(word, NUM_CHARS);

      reverseString(word);

      /* Ask the user if he or she wishes to enter another word */
      cout << "\n\tDo you wish to enter another word? ";
      cin.get(again);

      /* Input validation */
      while (toupper(again) != 'Y' && toupper(again) != 'N')
      {
         cout << "\n\tEnter 'Y' or 'N': ";
         cin.ignore();
         cin.get(again);
      }

      if (toupper(again) == 'Y')
      {
         cin.getline(word, NUM_CHARS);

      }
      else
      {
         cout << "\n\t!yeB dooG\n\n";
      }
   } while (toupper(again) == 'Y');

   /* Frees the memory */
   delete[] word;
   word = nullptr;

   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: reverseString

   This function accepts a pointer to a C-string as argument.
   After the string is reversed, using the swap function, the
   word is displayed backwards.
   ********************************************************** */

void reverseString(char *revPtr)
{
   int forward = 0,
       backward = strlen(revPtr);

   while (forward < backward)
   {
      --backward;

      swap(*(revPtr + forward), *(revPtr + backward));

      forward++;
   }

   cout << "\tThis is your word backwards: " << revPtr << "\n";
}

Example Output:



Programming Challenge 10.1 - String Length

/* String Length - This program contains a function that returns an
   integer and accepts a pointer to a C-string as an argument. The
   function counts the number of characters in the string and returns
   that number. The user is asked to input a string, which is passed
   to the function, and then displays the function's return value. */

#include "Utility.h"

/* Counts characters in a C-string, returns the character count. */
int countChars(const char *);

int main()
{
   const int NUM_CHARS = 100;

   /* Char array to hold a sentence */
   char *sentence = new char[NUM_CHARS]();

   char again = ' ';
   int  letterCount = 0;

   do
   {
      /* Get a sentence from the user */
      cout << "\n\t\t\tCHARACTER COUNTER\n\n"
           << "\tEnter a sentence of up to " << (NUM_CHARS - 1)
           << " characters: ";
      cin.getline(sentence, NUM_CHARS);

      /* Display the number of characters in the string */
      cout << "\n\tThis sentence contains "
           << (letterCount = countChars(sentence))
           << " characters.\n";

      /* Ask if the user wishes to enter another sentence */
      cout << "\n\tDo you wish to enter another sentence ('Y' or 'N')? ";
      cin.get(again);

      /* Input validation */
      while (toupper(again) != 'Y' && toupper(again) != 'N')
      {
         cout << "\n\tEnter 'Y' or 'N' to enter another sentence: ";
         cin.ignore();
         cin.get(again);
      }

      /* If again is 'y', another sentence may be entered. */
      if (toupper(again) == 'Y')
      {
         cin.getline(sentence, NUM_CHARS);
      }
      else
      {
         cout << "\n\tGood bye!\n\n";
      }

   } while (toupper(again) == 'Y');

   /* Frees the memory */
   delete[] sentence;
   sentence = nullptr;

   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: countChars

   This function contains chrPtr, pointing to the C-string
   containing a sentence the user entered. It counts the
   characters and returns this number as an integer value.
   ********************************************************** */

int countChars(const char *chrPtr)
{
   int numChars = 0;

   while (*chrPtr != '\0')
   {
       numChars++;
      *chrPtr++;
   }

   return numChars;
}

Example Output:



Monday, April 3, 2017

Half Way

It is time to celebrate! Today, I officially reached the half-way point, meaning to be half way through the book, after about 6 months. Last year in September I started my journey, this blog followed about a month, and 3 chapters, later. So instead of writing about my experiences with this chapter, I will tell you about my past experience with programming and programming languages. 

I started out with the Basic language, back in the day on a Commodore 64. I never got very far into it, mostly typing in long listings, then enjoying some game or other. Around 2005 another programming language entered my life, Visual Basic this time. It and I haven't been compatible to each other. Quite frankly, I didn't understand the language, the syntax, I didn't like it, yet had to learn it. I failed, and since I wouldn't need it anyway, simply gave up on it. Yet I always wanted to write my own game someday, and this would most likely require to learn a language to realize it. 

2015 was the year of experimenting around with some programming languages. I tried Java, didn't like it, C# - which I tried once before, and seemed a good choice, then Perl and finally Monoscript. It is part of Unity, so I did some tutorials the company had to offer, and bought a book or two. Eventually I managed to finish the tutorials, but when it came to realize something on my own, I could not. It was the lack of knowledge about pointers, arrays, classes, you name it. Sticking to the approach of taking a shortcut ended in the realization that without solid knowledge of at least one language, my dream will remain to be just that, and as I'm not the person to give up on anything, no matter how long it takes me to get there, this was no option.

Last year, then, closing the circle, I found the book Starting Out With C++ and bought it. It wasn't cheap, but good things come with a price-tag attached to it, so I said to myself - Here goes nothing! bought it, and finally found not only a resource I could work with, but also the language most compatible to my style. (For lack of any better word). To sum it up, despite having knowledge of html, css, melscript, some basic, close to no knowledge of VB and some other languages, I was - and still consider myself to be, a newbie. 

It started out easy, "Hello World!", and, looking back, hasn't gotten any more difficult since then. Sounds strange to say, when looking at some of my most recent struggles, particularly the one concerning the discovery of mode(s) in an array of integers. That is to say that most of the time it wasn't coming up with a way to write code for the challenges, but rather to understand the nature of the problem, and to find a way to solve it. 

Here is an example. The median function I have written for one of the challenges. Below you find part of the code that does all the work: 

   int      middleElem = numels / 2,
             midLower = 0,
             midUpper = 0;

   numels % 2 == 0 ? midLower = *(numList + middleElem - 1),
                                  midUpper = *(numList + middleElem),
                                  median = (midUpper + midLower) / 2 :
                                  median = *(numList + middleElem);

But how did I come up with this ternary, or rather this particular solution? At first I thought that I would use the subtle hint given in the problem statement in my code somehow: 

"If the set contains an even number of values, the median is the mean or average, of the two middle values."

It was clear that if there is an even number, there has to be an odd number, and to find it would necessitate to use the modulo operator, to find out whether the number of elements is odd or even. To find a mode in an odd-numbered set would be straightforward, so my first thought was to implement a binary-search, which would find the middle-value. I tried, then reconsidered. 

What would a binary-search actually do? It would solve one half of the problem, but how would this look like? Should I call this function to do the search if a number is odd, and then call another function if it isn't? No, there must be a more straightforward solution to this, revolving around the central idea of odd and even numbers. I sat back, thinking, and taking a closer look at a different part of my code:

  *(numList + startScan) = minEl;

This line is part of the sorting function. And seeing how startScan is used there, and how it is used in the search function, I started seeing a connection to my problem, and how I can solve it. I knew that it is about odd and even numbers, and that an even-numbered array would contain two middle values, one in the upper, one in the lower half. So why don't I use this, initialize middleElem to calculate the halfs, reverse the condition by assigning to variables the numbers in the upper half and in the lower half? This is what I did, and it worked. All because I found this connection between the line of code I so often used to perform a sort on numbers, I found the key to solve the problem, by combining everything in a single ternary operator. 

Ternary, in my opinion, is a misnomer. In or around chapters 7 and 8 I found out that it is very well possible to chain ternaries, there is practically no limit. You only have to replace the : with another condition. condition ? condition1 ? condition2 ? condition 3? x : y. I tried in one of my programs, but refrained from actually using the piece of code, even though it worked. Because something works doesn't mean you should use it, as it would guarantee to make it nigh impossible to read, as well as difficult to understand for others what the piece of code actually does. Ternary being a mighty tool making for short, yet still readable code, if done right. This is why I so like it, as in the above example, one line of code does it all. 

Back to this line of code once more:

*(numList + startScan) = minEl;

To discover that it holds the key to solve the above mentioned problem also was key to solve the Reverse Array, Array Expander and Element Shifter challenges. The only challenge has been to figure out the counters, as in one challenge the counter had to count up, the other down in one challenge, and in one of the others both had to count up. This took a while to find out, but was no major hurdle, just a matter of switching the counter variables around several times. And again the key has been a line of code from the sorting function:

*(numList + minIndex) = *(numList + startScan);

to come up with this one line in the Array Expander challenge:
 
*(expanded + count) = *(numbers + count); 

But what about pointers, since this chapter has been all about it, and I haven't yet lost a single word on them? Well, at first I felt a little intimidated and insecure in the early challenges, always thinking: Am I doing things right? Luckily the first couple of challenges fostered some confidence. This was quickly destroyed by the mode challenge. 3 weeks, the longest time it has taken to finish a challenge! And it wasn't even the pointers, but enough of this one, I will not wish to be reminded of it - ever - period. Summarily I can say that I feel rather comfortable working with pointers now, and that I very much like what I can do with them, as well as the pointer notation. I like it more than array notation, so I think you will see more of it in the near future. 

For now I deserve some rest, before I dive into the 10th chapter. This one will be about C-Strings, Characters and the string Class, which I do not yet know I will like, the topics, that is. But as it is a part of the book, I will make the best of it. Rest assured that I will be back soon with more code. Until then I wish my fellow learners that they be soon finished with this chapter, and that they be able to make such important discoveries as i did. To my readers, regular or otherwise, thanks for your visit!

Programming Challenge 9.13 - Movie Statistics

/* Movie Statistics - This program can be used to gather statistical
   data about the number of movies college students see in a month.
   The program performs the following steps:
 
      * Ask the user how many students were surveyed. An array
        of integers with this many elements is then dynamically
        allocated.

      * The user is allowed to enter the number of movies each
        student saw into the array.

      * The average, median, and mode of the values entered is
        calculated and displayed. The functions written in
        Programming Challenge 9.8 and 9.9 are used to calculate
        the median and mode.

   Input Validation: No negative numbers are accepted for input. */

#include "Utility.h"

/* Function prototypes */
void mainMenu();
void getNumbers(int *, int);
void sortNumbers(int *, int);
double getAverage(int *, int);
double getMedian(int *, int);
void getFrequency(int *, int *, int);
void sortStats(int *, int *, int);
int getMode(int *, int *, int *, int);
void displayData(int *, double, double, int, int);
void displayHistogram(int *, int *, int);
void freeMem(int *, int *, int *);

int main()
{
   mainMenu();

   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: mainMenu

   This function offers a menu with the following options:

      * Enter survey data
      * View survey results
      * View histogram
      * Quit

   It calls all other functions to process the data once
   entered.
   ********************************************************** */

void mainMenu()
{
   const int SURVEY_DATA = 1,
             VIEW_RESULTS = 2,
             VIEW_HISTOGRAM = 3,
             QUIT = 4;

   int *numMovies = nullptr;
   int *frequency = nullptr;
   int *modes = nullptr;

   int surveyed = 0,
       mode = 0,
       menuItem = 0;

   double average = 0.0,
          median = 0.0;

   do
   {
      cout << "\n\n\tOka Gakuen Movie Club\n\n"
           << "\n\tMAIN MENU\n"
           << "\t--------------------\n"
           << "\t1. ENTER SURVEY DATA\n"
           << "\t2. VIEW SURVEY RESULTS\n"
           << "\t3. VIEW HISTOGRAM\n"
           << "\t4. QUIT\n\n"
           << "\tSELECT ITEM: ";
      cin >> menuItem;

      /* Input Validation */
      while (menuItem < SURVEY_DATA || menuItem > QUIT)
      {
         cin >> menuItem;
      }

      switch (menuItem)
      {
         case SURVEY_DATA:
         {      
            cout << "\n\n\tHow many students have been surveyed? ";
            cin >> surveyed;

            /* Dymically allocated arrays to hold the number of
               movies each student has watched, the frequency of
               numbers, and the modes */
            numMovies = new int[surveyed]();
            frequency = new int[surveyed]();
            modes = new int[surveyed]();

            /* Gets the number of movies each student watched */
            getNumbers(numMovies, surveyed);

            /* Sorts the numbers using an selection-sort algorithm */
            sortNumbers(numMovies, surveyed);

            /* Calculates the average number of movies watched */
            average = getAverage(numMovies, surveyed);

            /* Determines and returns the median */
            median = getMedian(numMovies, surveyed);

            /* Determines and stores the frequency of numbers
               in numMovies */
            getFrequency(numMovies, frequency, surveyed);

            /* Sorts the elements in numList and frequency in
               descending order using an dual-selection-sort
               algorithm */
            sortStats(numMovies, frequency, surveyed);

            /* Determines and stores the mode(s) in modes if there
               are any. If there is no mode, -1 is returned. */
            mode = getMode(numMovies, frequency, modes, surveyed);
         }
         break;

         case VIEW_RESULTS:
         {
            displayData(modes, average, median, mode, surveyed);
         }
         break;

         case VIEW_HISTOGRAM:
         {
            displayHistogram(numMovies, frequency, surveyed);
         }
         break;

         case QUIT:
         {
            cout << "\n\tNow closing the program ...\n\n";
         }
         break;
      }

   } while (menuItem != QUIT);

   /* Frees the memory */
   freeMem(numMovies, frequency, modes);
}

/* **********************************************************
   Definition: getNumbers

   This function accepts numMovies and surveyed, indicating
   the number of elements contained in the array. It asks the
   user to enter the number of movies each student watched.
   ********************************************************** */

void getNumbers(int *numMovies, int surveyed)
{
   cout << "\n\n\tNumber of movies watched:\n"
        << "\t------------------------\n";

   for (int index = 0; index < surveyed; index++)
   {
      cout << "\tStudent #" << (index + 1) << ": ";
      cin >> *(numMovies + index);

      /* Input Validation */
      while (*(numMovies + index) <= 0)
      {
         cout << "\tStudent #" << (index + 1) << ": ";
         cin >> *(numMovies + index);
      }
   }
}

/* **********************************************************
   Definition: sortNumbers

   This function accepts numMovies and surveyed as arguments.
   It uses a selection-sort algorithm to sort the numbers in
   an ascending order.
   ********************************************************** */

void sortNumbers(int *numMovies, int surveyed)
{
   int startScan = 0,
       index = 0,
       minIndex = 0,
       minEl = 0;

   for (startScan = 0; startScan < surveyed; startScan++)
   {
      minIndex = startScan;
      minEl = *(numMovies + startScan);

      for (index = startScan + 1; index < surveyed; index++)
      {
         if (*(numMovies + index) < minEl)
         {
            minEl = *(numMovies + index);
            minIndex = index;
         }
      }

      *(numMovies + minIndex) = *(numMovies + startScan);
      *(numMovies + startScan) = minEl;
   }
}

/* **********************************************************
   Definition: getAverage

   This function accepts numMovies and surveyed as arguments.
   It calculates the average number of movies watched. This
   number is returned from the function.
   ********************************************************** */

double getAverage(int *numMovies, int surveyed)
{
   double total = 0.0;
   double average = 0.0;

   for (int index = 0; index < surveyed; index++)
   {
      total += *(numMovies + index);
   }

   return average = total / surveyed;
}

/* **********************************************************
   Definition: getMedian

   This function accepts numMovies and surveyed as arguments.
   It determines the median and returns it.
   ********************************************************** */

double getMedian(int *numMovies, int surveyed)
{
   double median = 0.0,
          midLower = 0.0,
          midUpper = 0.0;

   int      middleElem = surveyed / 2;
 
   surveyed % 2 == 0 ? midLower = *(numMovies + middleElem - 1),
                       midUpper = *(numMovies + middleElem),
                       median = (midUpper + midLower) / 2 :
                       median = *(numMovies + middleElem);

   return median;
}

/* **********************************************************
   Definition: getFrequency

   This function accepts numMovies, frequency and surveyed as
   arguments. It counts the numbers stored in numMovies,
   totals these numbers, and stores the result in frequency.
   ********************************************************** */

void getFrequency(int *numMovies, int *frequency, int surveyed)
{
   int total = 0,
       count = 0;

   /* Find numbers that are equal, and count these */
   for (int index = 0; index < surveyed; index++)
   {
      total = 0;
      count = 1;

      while (*(numMovies + index) == *(numMovies + index + 1))
      {
         count++;
         index++;
      }

      total = count;
      *(frequency + index) = total;
   }
}

/* **********************************************************
   Definition: sortStats

   This function accepts numMovies, frequency and surveyed as
   arguments. It uses a dual-selection-sort algorithm to sort
   numMovies and frequency in descending order.
   ********************************************************** */

void sortStats(int *numMovies, int *frequency, int surveyed)
{
   int startScan = 0,
       index = 0,
       maxIndex = 0,
       tempList = 0,
       maxEl = 0;

   for (startScan = 0; startScan < surveyed; startScan++)
   {
      maxIndex = startScan;
      maxEl = *(frequency + startScan);
      tempList = *(numMovies + startScan);

      for (index = startScan + 1; index < surveyed; index++)
      {
         if (*(frequency + index) > maxEl)
         {
            maxEl = *(frequency + index);
            tempList = *(numMovies + index);
            maxIndex = index;
         }
      }

      *(frequency + maxIndex) = *(frequency + startScan);
      *(numMovies + maxIndex) = *(numMovies + startScan);

      *(frequency + startScan) = maxEl;
      *(numMovies + startScan) = tempList;
   }
}

/* **********************************************************
   Definition: getMode

   This function accepts numMovies, frequency, modes, and
   surveyed as arguments. First the function determines
   whether there is a mode, and if there is, it is stored in
   modes. If there is no mode, -1 is returned.
   ********************************************************** */

int getMode(int *numMovies, int *frequency, int *modes, int surveyed)
{
   int index = 0,
       frHigh = 0,
       mode = 0;

   /* If all numbers in numList are the same, 3, 3, 3, or if
      frequency equals 1, meaning that no number has a higher
      occurence than any others, mode gets -1. */
   if (*(numMovies + index) == *(numMovies + index + 1) ||
       *(frequency + index) == 1)
   {
      mode = -1;
   }

   for (int index = 0; index < surveyed; index++)
   {
      if (*(frequency + index) > frHigh)
      {
         frHigh = *(frequency + index);
      }

      if (frHigh == *(frequency + index))
      {
         *(modes + index) = *(numMovies + index);
      }
   }

   return mode;
}

/* **********************************************************
   Definition: displayData

   This function accepts modes, average, median, mode, and
   surveyed as arguments. It displays the mode(s), average
   number of movies watched by all students, and the median
   or middle value.
   ********************************************************** */

void displayData(int *modes, double average, double median,
                 int mode, int surveyed)
{
   cout << fixed << showpoint << setprecision(2);

   cout << "\n\n\tOka Gakuen Movie Club - Survey Results\n\n"
        << "\n\tAccording to our survey, in which " << surveyed
        << " students have\n"
        << "\tkindly participated, the average number of movies\n"
        << "\twatched has been " << average << "\n\n"
        << "\tThe median, or middle value we found, was " << median
        << "\n\n";

   if (mode != -1)
   {
      cout << "\tThese mode(s), or numbers occuring most frequently\n"
           << "\tin our survey, have been discovered: \n\n";

      for (int index = 0; index < surveyed; index++)
      {
         if (*(modes + index) > 0)
         {
            cout << "\tMode #" << (index + 1) << setw(14) << right
               << *(modes + index) << " \n";
         }
      }
   }
   else
   {
      cout << "\n\tOur survey does not contain any modes ...\n\n";
   }
}


/* **********************************************************
   Definition: displayHistogram

   This function accepts numMovies, frequency and surveyed as
   arguments. It displays the number of movies watched. The
   numbers are displayed in order of frequency. If there are
   no numbers with higher frequency, then the numbers are
   displayed from lowest to highest.
   ********************************************************** */

void displayHistogram(int *numMovies, int *frequency, int surveyed)
{
   int index = 0,
       total = 0,
       count = 0;

   cout << "\n\n\tOka Gakuen Movie Club - Survey Histogram\n\n"
        << "\tMOVIES WATCHED: " << setw(17) << right
        << "FREQUENCY:" << setw(17) << right
        << "HISTOGRAM:\n";

   cout << "\t--------------" << setw(18) << right
        << "---------" << setw(17) << right
        << "---------\n";

   for (index = 0; index < surveyed; index++)
   {
      total = 0;

      if (*(frequency + index) > 0)
      {
         total = *(frequency + index);

         cout << setw(11) << right << *(numMovies + index)
              << setw(22) << right << *(frequency + index)
              << setw(15) << right;

         for (count = 1; count <= total; ++count)
         {
            cout << "*";
         }
         cout << "\n";
      }
   }
}

/* **********************************************************
   Definition: freeMem

   This function accepts numMovies, frequency, and modes as
   arguments. It frees the allocated memory before the
   program exits.
   ********************************************************** */

void freeMem(int *numMovies, int *frequency, int *modes)
{
   delete[] numMovies;
   delete[] frequency;
   delete[] modes;

   numMovies = nullptr;
   frequency = nullptr;
   modes = nullptr;
}

Example Output:








Sunday, April 2, 2017

Programming Challenge 9.12 - Element Shifter

/* Element Shifter - This program contains a function that accepts an
   int array and the array's size as arguments. The function creates
   a new array that is one element larger than the argument array. The
   first element of the new array is set to 0. Element 0 of the argument
   array is copied to element 1 of the new array, element 1 of the
   argument array is copied to element 2 of the new array, and so forth.
   The function returns a pointer to the new array. */

#include "Utility.h"

/* Function prototypes */
void getNumbers(int *, int);
void displayNumbers(const int *, const int);
int *shiftElements(const int *, int &, const int);
void displayShifted(const int *, const int);
void freeMem(int *, int *);

int main()
{
   int *numbers = nullptr;
   int *shifted = nullptr;

   int numels = 0,
       elemSize = 0;

   /* Ask for the number of elements the array should to hold */
   cout << "\n\tELEMENT SHIFTER\n\n"
        << "\tHow many numbers should your set contain? ";
   cin >> numels;

   /* Input Validation */
   while (numels <= 0)
   {
      cout << "\n\tInvalid Input!\n"
           << "\tHow many numbers should your set contain? ";
      cin >> numels;
   }

   /* Allocates a new array to hold the numbers */
   numbers = new int[numels];

   /* Creates a set of random numbers to fill the numbers array */
   getNumbers(numbers, numels);

   /* Displays the numbers in their original order */
   displayNumbers(numbers, numels);

   cout << "\n\n\tNow shifting the elements by one ...\n\n";

   /* Shifts the elements in the argument array */
   shifted = shiftElements(numbers, elemSize, numels);

   /* Displays the new array with elements shifted by one
      position */
   displayShifted(shifted, elemSize);

   /* Frees the memory */
   freeMem(numbers, shifted);

   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: getNumbers

   This function accepts numbers and numels as arguments. It
   fills numbers with (pseudo)random numbers in the range of
   1 through 200.
   ********************************************************** */

void getNumbers(int *numbers, int numels)
{
   const int MIN_NUM = 1,
             MAX_NUM = 200;

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

   for (int index = 0; index < numels; index++)
   {
      *(numbers + index) = (rand() % (MAX_NUM - MIN_NUM + 1) + MIN_NUM);
   }
}

/* **********************************************************
   Definition: displayNumbers

   This function accepts numbers and numels as arguments. It
   displays the numbers in their original order.
   ********************************************************** */

void displayNumbers(const int *numbers, const int numels)
{
   cout << "\n\tThese are your numbers in their original order:\n\n";

   for (int index = 0; index < numels; index++)
   {
      cout << "\t" << *(numbers + index) << " \n";
   }
}

/* **********************************************************
   Definition: shiftElements

   This function accepts numbers, elemSize, and numels as
   arguments. It creates a new array, one element larger than
   numbers, the first element being initialized to 0. The
   elements are shifted by one position, each time an element
   from the argument array is copied to the new array. When
   finished, a pointer to the new array is returned.
   ********************************************************** */

int *shiftElements(const int *numbers, int &elemSize, const int numels)
{
   int *elemShifter = nullptr;

   int firstElem = 0,
       nextElem = 0;

   elemSize = numels + 1;

   /* Allocates a new array, one element larger than the argument
      array, to hold the shifted elements */
   elemShifter = new int[elemSize]();

   while (firstElem < numels)
   {
      ++nextElem;

      *(elemShifter + nextElem) = *(numbers + firstElem);

      ++firstElem;
   }

   return elemShifter;
}

/* **********************************************************
   Definition: displayShifted

   This function accepts shifted and elemSize as arguments.
   It displays the numbers in the new array, after having
   been shifted by 1 position.
   ********************************************************** */

void displayShifted(const int *shifted, const int elemSize)
{
   cout << "\n\tThese are your numbers after being shifted "
        << "by 1 position:\n\n";

   for (int index = 0; index < elemSize; index++)
   {
      cout << "\t" << *(shifted + index) << " \n";
   }
}

/* **********************************************************
   Definition: freeMem

   This function accepts numbers and shifted as arguments. It
   frees the memory before the program exits.
   ********************************************************** */

void freeMem(int *numbers, int *shifted)
{
   delete[] numbers;
   delete[] shifted;

   numbers = nullptr;
   shifted = nullptr;
}

Example Output:




Programming Challenge 9.11 - Array Expander

/* Array Expander - This program contains a function that accepts an
   int array and the array's size as arguments. The function creates
   a new array that is twice the size of the argument array. The
   function copies the contents of the argument array to the new array
   and initialize the unused elements of the second array with 0. The
   function returns a pointer to the new array. */

#include "Utility.h"

/* Function prototypes */
void getNumbers(int *, int);
int *expandArray(const int *, int &, int);
void displayOriginal(const int *, const int);
void displayCopy(const int *, const int);
void freeMem(int *, int*);

int main()
{
   int *numbers = nullptr;
   int *arrExpander = nullptr;

   int numels = 0,
       expSize = 0;

   /* Get the initial number of elements the array should hold */
   cout << "\n\tARRAY EXPANDER\n\n"
        << "\tHow many numbers should your array contain? ";
   cin >> numels;

   /* Allocates a new array to hold the numbers */
   numbers = new int[numels]();

   /* Creates a set of random numbers to fill the numbers array */
   getNumbers(numbers, numels);

   /* Displays the original array and its contents */
   displayOriginal(numbers, numels);

   cout << "\n\n\tYour array will now be copied and expanded ...\n\n";

   /* Expands the array to hold twice the number of elements as its
      original */
   arrExpander = expandArray(numbers, expSize, numels);

   /* Displays the copy of the array */
   displayCopy(arrExpander, expSize);

   pauseSystem();
   return 0;
}

/* **********************************************************
   Definition: getNumbers

   This function accepts numbers and numels as arguments. It
   fills numbers with (pseudo)random numbers in the range of
   1 through 200.
   ********************************************************** */

void getNumbers(int *numbers, int numels)
{
   const int MIN_NUM = 1,
             MAX_NUM = 200;

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

   for (int index = 0; index < numels; index++)
   {
      *(numbers + index) = (rand() % (MAX_NUM - MIN_NUM + 1) + MIN_NUM);
   }
}

/* **********************************************************
   Definition: displayOriginal

   This function accepts numbers and numels as arguments. It
   displays the original array.
   ********************************************************** */

void displayOriginal(const int *numbers, const int numels)
{
   cout << "\n\tThis is how your original array looks like:\n\n";

   for (int index = 0; index < numels; index++)
   {
      cout << "\t" << *(numbers + index) << "\n";
   }

   cout << "\n\tIt holds " << numels << " elements.\n";
}


/* **********************************************************
   Definition: displayCopy

   This function accepts expanded and numels as arguments. It
   displays the content of the argument array's copy.
   ********************************************************** */

void displayCopy(const int *expanded, const int expSize)
{
   cout << "\n\tThis is how your array's copy looks like:\n\n";

   for (int index = 0; index < expSize; index++)
   {
      cout << "\t" << *(expanded + index) << "\n";
   }

   cout << "\n\tIt can now hold " << expSize << " elements!\n";
}

/* **********************************************************
   Definition: arrayExpander

   This function accepts numbers and numels as arguments. It
   creates a copy of the argument array, twice the size of
   the original. The elements of the copy are initialized to
   0, then the argument array's content is copied into the
   copy. A pointer is returned from the function pointing to
   the copy of the argument array.
   ********************************************************** */

int *expandArray(const int *numbers, int &expSize, const int numels)
{
   int *expanded = nullptr;

   int count = 0;

   expSize = numels * 2;
  
   /* Allocates memory for an array to hold twice the number
      of elements as the original */
   expanded = new int[expSize]();

   while (count < numels)
   {
      *(expanded + count) = *(numbers + count);
     
      ++count;
   }
  
   /* Returns a pointer to the copy of the argument array */
   return expanded;
}

/* **********************************************************
   Definition: freeMem

   This function accepts numbers expander as arguments. It
   frees the memory before the program exits.
   ********************************************************** */

void freeMem(int *numbers, int *arrExpander)
{
   delete[] numbers;
   delete[] arrExpander;

   numbers = nullptr;
   arrExpander = nullptr;
}

Example Output: