/* Movie Statistics - This program can be used to gather statisticaldata 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 arrayof integers with this many elements is then dynamicallyallocated.* The user is allowed to enter the number of movies eachstudent saw into the array.* The average, median, and mode of the values entered iscalculated and displayed. The functions written inProgramming Challenge 9.8 and 9.9 are used to calculatethe 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: mainMenuThis function offers a menu with the following options:* Enter survey data* View survey results* View histogram* QuitIt calls all other functions to process the data onceentered.********************************************************** */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 ofmovies each student has watched, the frequency ofnumbers, 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 numbersin numMovies */getFrequency(numMovies, frequency, surveyed);/* Sorts the elements in numList and frequency indescending order using an dual-selection-sortalgorithm */sortStats(numMovies, frequency, surveyed);/* Determines and stores the mode(s) in modes if thereare 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: getNumbersThis function accepts numMovies and surveyed, indicatingthe number of elements contained in the array. It asks theuser 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: sortNumbersThis function accepts numMovies and surveyed as arguments.It uses a selection-sort algorithm to sort the numbers inan 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: getAverageThis function accepts numMovies and surveyed as arguments.It calculates the average number of movies watched. Thisnumber 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: getMedianThis 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: getFrequencyThis function accepts numMovies, frequency and surveyed asarguments. 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: sortStatsThis function accepts numMovies, frequency and surveyed asarguments. It uses a dual-selection-sort algorithm to sortnumMovies 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: getModeThis function accepts numMovies, frequency, modes, andsurveyed as arguments. First the function determineswhether there is a mode, and if there is, it is stored inmodes. 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 iffrequency equals 1, meaning that no number has a higheroccurence 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: displayDataThis function accepts modes, average, median, mode, andsurveyed as arguments. It displays the mode(s), averagenumber of movies watched by all students, and the medianor 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: displayHistogramThis function accepts numMovies, frequency and surveyed asarguments. It displays the number of movies watched. Thenumbers are displayed in order of frequency. If there areno numbers with higher frequency, then the numbers aredisplayed 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: freeMemThis function accepts numMovies, frequency, and modes asarguments. It frees the allocated memory before theprogram exits.********************************************************** */void freeMem(int *numMovies, int *frequency, int *modes){delete[] numMovies;delete[] frequency;delete[] modes;numMovies = nullptr;frequency = nullptr;modes = nullptr;}
Monday, April 3, 2017
Programming Challenge 9.13 - Movie Statistics
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:
Programming Challenge 9.10 - Reverse Array
/* Reverse Array - This program contains a function that accepts an int
array and the array's size as arguments. The function creates a copy
of the array, except that the element values are reversed in the copy.
The function returns a pointer to the new array. */
#include "Utility.h"
/* Function prototypes */
void getNumbers(int *, int);
int *reverseNumbers(const int *, const int);
void displayNumbers(const int *, const int);
void displayReverse(const int *, const int);
void freeMem(int *, int *);
int main()
{
int *numbers = nullptr;
int *revNumbers = nullptr;
int numels = 0;
/* Get the initial number of elements the array should contain */
cout << "\tREVERSE NUMBERS\n\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);
/* Creates a copy of numbers and fills the copy with the numbers
in reverse order */
revNumbers = reverseNumbers(numbers, numels);
/* Displays the numbers in reverse order */
displayReverse(revNumbers, numels);
/* Frees the memory */
freeMem(numbers, revNumbers);
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: reverseNumbers
This function accepts numbers and numels as arguments. It
creates a copy of the array, and reverses the numbers. A
pointer to the copy containing the numbers in reverse
order is returned.
********************************************************** */
int *reverseNumbers(const int *numbers, const int numels)
{
int *revNumbers = nullptr;
int firstElem = 0,
lastElem = numels;
/* Allocates a new array to hold the copy of numbers in
reverse order */
revNumbers = new int[numels]();
while (lastElem > 0)
{
--lastElem;
*(revNumbers + firstElem) = *(numbers + lastElem);
++firstElem;
}
/* Returns a pointer to the new array */
return revNumbers;
}
/* **********************************************************
Definition: displayReverse
This function accepts revNumbers and numels as arguments. It
displays the numbers in reverse order.
********************************************************** */
void displayReverse(const int *revNumbers, const int numels)
{
cout << "\n\tThese are your numbers in reverse order:\n\n";
for (int index = 0; index < numels; index++)
{
cout << "\t" << *(revNumbers + index) << " \n";
}
}
/* **********************************************************
Definition: freeMem
This function accepts numbers and numels as arguments. It
frees the memory before the program exits.
********************************************************** */
void freeMem(int *numbers, int *revNumbers)
{
delete[] numbers;
delete[] revNumbers;
numbers = nullptr;
revNumbers = nullptr;
}
Example Output:
Saturday, April 1, 2017
Programming Challenge 9.9 - Median Function
/* Median Function - In statistics, when a set of values is sorted in
ascending or descending order, its median is the middle value. If
the set contains an even number of values, the median is the mean,
or average, of the two middle values.
This program contains a function that accepts the following:
* An array of integers
* An integer that indicates the number of elements in the array
The function determines the median of the array. This value is
returned as double. (The numbers are sorted).
Pointer prowess is demonstrated by using pointer notation instead
of array notation. */
#include "Utility.h"
void getNumbers(int *, int);
void sortNumbers(int *, int);
double getMedian(int *, int);
void freeMem(int *);
int main()
{
/* Dynamically allocated array to
hold a list of numbers */
int *numList = nullptr;
int numels = 0;
double median = 0.0;
cout << "\n\tMEDIAN DISCOVERY FUNCTION\n\n"
<< "\n\tHow many elements should your set of numbers contain? ";
cin >> numels;
numList = new int[numels];
/* Gets a list of numbers by way of input */
getNumbers(numList, numels);
/* Sorts the numbers in ascending order by using an selection-sort
algorithm */
sortNumbers(numList, numels);
/* Determines and returns the median */
median = getMedian(numList, numels);
/* Display the median value */
cout << fixed << showpoint << setprecision(2);
cout << "\n\tThe median is: " << median << " ";
/* Frees the memory before the program exits */
freeMem(numList);
pauseSystem();
return 0;
}
/* **********************************************************
Definition: getNumbers
This function accepts numList and numels as arguments. The
numbers entered by the user are stored in numlist.
********************************************************** */
void getNumbers(int *numList, int numels)
{
cout << "\n\n\tPlease enter " << numels << " numbers:\n\n";
for (int index = 0; index < numels; index++)
{
cout << "\tNumber #" << (index + 1) << ": ";
cin >> *(numList + index);
}
cout << "\n";
}
/* **********************************************************
Definition: sortNumbers
This function accepts numList and numels as arguments. It
uses a selection-sort algorithm to sort the numbers in an
ascending order.
********************************************************** */
void sortNumbers(int *numList, int numels)
{
int startScan = 0,
index = 0,
minIndex = 0,
minEl = 0;
for (startScan = 0; startScan < numels; startScan++)
{
minIndex = startScan;
minEl = *(numList + startScan);
for (index = startScan + 1; index < numels; index++)
{
if (*(numList + index) < minEl)
{
minEl = *(numList + index);
minIndex = index;
}
}
*(numList + minIndex) = *(numList + startScan);
*(numList + startScan) = minEl;
}
cout << "\n\tYour numbers in sorted order:\n\n";
for (int index = 0; index < numels; index++)
{
cout << "\t" << *(numList + index) << " \n";
}
}
/* **********************************************************
Definition: getMedian
This function accepts numList and numels as arguments. It
determines the median and returns it. This is achieved by
using a ternary operator, that does the following:
* The first condition determines whether the number of
elements in the array is even or odd.
* If the number is even, midLower gets the middle value
found in the lower half of the array, and midUpper is
assigned the middle value at the upper half of the
array.
* Then the median is calculated by adding the middle
values and dividing the sum by 2.
* If the number of elements is odd, median gets the
middle element. The calculation to determine it has
already been carried out.
Once the median is found, it is returned.
********************************************************** */
double getMedian(int *numList, int numels)
{
double median = 0.0;
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);
return median;
}
/* **********************************************************
Definition: freeMem
This function accepts numList as argument. It frees the
allocated memory before the program exits.
********************************************************** */
void freeMem(int *numList)
{
delete[] numList;
numList = nullptr;
}
Example Output:
Monkey Business - Back with a vengance
Some of my regular visitors may remember my post about all the troubles I have had with finishing the Monkey Business programming challenge. As the title of this blog post suggests, it came back with a vengeance, this time with the Mode programming challenge. Before I share this story with you, catch a cup and make yourself comfortable, as I foresee that this post is going to be a long one.
![]() |
| Picture Copyright: My own work, a free for all. |
When I started with this challenge, it seemed to turn out to be quite easy, a day maybe two and it should be done. What was asked for seemed to be clear enough:
"Create an array, fill it with numbers, discover the highest number, and return it. Or return -1 if no number occurs more frequently than any others."
This lulled me into a false sense of security, and with my guard down, no research about mode(s) done, I simply planned out my program, all the functions it should have, so on so forth. To finish writing the code was taking half a day at most. Everything was working, the code along with some screenshots ready to be uploaded, or so I thought. Then I started thinking ... and instead of uploading the supposedly finished program, I started doing some research on the topic of mode(s).
The very first thing I learned is that a set of numbers can contain more than one mode. Most of the examples I found were looking like this: 1, 2, 2, 2, 3, 3, 3 making the modes of this set 2 and 3. Up to this point I wasn't considering to change any of my existing code, because the challenge didn't ask to return more than one mode, but only the mode, should there be any, or -1 if none is discovered. This last condition has been covered by my original code. This newfound knowledge then led me to believe that if a set of numbers looks like this: 2, 2, 3, 3, 4, 4, 5, 5 it does not contain a mode. Or this set: 3, 3, 3, 4, 4, 4 both numbers are there 3 times, so there is no mode.
Of course this had to be taken into consideration, so I was trying to change my code accordingly. I failed, and failed, and failed some more. I was working on it for days and all my efforts led to my having to start over. I eventually reached the point, about 7 days in, I lost all hope of ever finding a way to get this problem solved. In desperate need for help I sought help in a coding community called http://www.cplusplus.com/ which I suppose many of you do know. Stating my problem according to what I thought was the core of my problem, I asked for a simple line of code, an if-statement, which I couldn't come up with, should suffice.
In the course of an exchange between an experienced member going by the nick of lastchance who helped me out so much, I discovered what the real problem was. At first a mere question was asked, that - by knowing at least something about mode(s) I was able to answer easily: 1, 2, 2, 3, 3, 4, 4, 5 which, do I think, is or are the mode(s)? My answer was, 2, 3, and 4, because they both occur at least two times making it three modes. Suffice to say that this question alone caused me to feel very stupid at first, but in turn helped me to discover the core of the actual problem.
This changed my view of the problem I was in part causing myself, by knowing that there can be both a single as well as more than one mode. Still, the problem to solve was in part still the same:
A set like this 1, 2, 2, 3, 3, 4, according to the websites explaining modes in statistics, has two modes, and a mode is the number occurring most frequently. It should take some more time to learn from lastchance that 2, 2, 2, 3, 3, 3 is containing two modes, 2 and 3, so making it a set of two modes.
I found out about the fact myself by visiting calculatorsoup,com a great website for doing all sorts of calculations, among others, all explaining that:
"Mode is the value or values in the data set that occur most frequently."
Yet, when entering 2, 2, 3, 3, 4, 4 not only the above mentioned website but all others as well, would say that the modes are 2, 3, 4. lastchance provided a code example delivering much the same result. This, then, after numerous failed attempts to return -1 if there is in fact more than one mode, I considered adding another array containing the mode(s), and having the function return -1 if there indeed is no mode, in light of this new discovery. Without this the program would not be complete. Also a histogram would have been nice to have.
With this I started out too plan and write the umpteenth version of the program. This time it would work out, or so I thought. Until completion I found about a major problem that made it yet another failed attempt in solving the challenge. The reason for failing the way it did was not very obvious, and the problem as such surfaced only after being finished writing the code. Up to this point i was working with simple input to fill numList, the array containing all the numbers.
When entering 1, 1, 2, 2, 3, 3 the output as far as modes is concerned was correct, histogram, frequency and numbers also. Then I entered the following sequence: 1, 2, 1, 2, 1, 2, 1, 2 expecting that the output would be:
mode(s): 1
mode(s): 2
Instead I got both 1 and two displayed numerous times, each being counted only once by the function that determines the frequency of numbers. My first instinct told me that this is merely a matter of changing the if statement dealing with output of the modes, which, in its initial version looked like this:
if (*(mutiMode + index) > 0 && *(multiMode + index) != *(multiMode + index + 1)
{
cout << "Mode(s): " << *(multiMode + index) << "\n";
}
This didn't help at all. Remember the word histogram! The output from this function was the same as the one in the mode function: 1, 2, 1, 2, 1, 2, 1, 2 freq: 1 ..... 1. In conclusion adding the same condition into this function as well, hoping for the correct result, being 1, 2 - 2, 2. Of course it didn't work out that way. Next thing I tried to change was the function taking care of counting the frequency, again, no luck. It has gotten so far that I even changed my sorting function, which I only have had one initially, so that it would sort by numbers not frequency. The lesson to be learned, which I learned the hard way, is this:
"If parts of your code do not work they are supposed to, don't try to add fixes in different parts of your code, because you are likely to introduce even more errors."
But what was the problem, then? In one word: Sorting. As mentioned, I had one sorting function, sorting both frequency and numList in descending order. In my next revision I had one for numList one for frequency, until in my final version I had one for frequency, and a dual-sort for both the arrays which then led to working code, doing as it should. Although I must admit that the histogram looks a bit strange as far as output of numbers goes. This is something that I considered to be fine as is, as long as the program is doing the job it is supposed to.
So, to my fellow learners, as well as readers old and new, whom I heartily welcome to my humble abode, I hope you will be able to learn something from this. And my hope for the next challenge, which involves writing a function to calculate the median, is that it turns out to be an easy one! With this, it is time to get back to my IDE, and write some more code.
Programming Challenge 9.8 - Mode Function
/* Mode Function - In statistics, the mode of a set of values is the
value that occurs most often or with the greatest frequency. This
program contains a function that accepts the following arguments:
* An array of integers
* An integer that indicates the number of elements in the array
The function determines the mode of the array. That is, it determines
which value in the array occurs most often. The mode is the value the
function returns. If the array has no mode (none of the values occur
more than once), the function returns -1. (The assumption is that the
array will always contain nonnegative values.)
Pointer prowess is demonstrated by using pointer notation instead of
array notation in this function. */
#include "Utility.h"
void getNumbers(int *, int);
void sortNumbers(int *, int);
void getFrequency(int *, int *, int);
void dualSort(int *, int *, int);
int getMode(int *, int *, int *, int);
void displayMode(int *, int);
void displayHistogram(int *, int *, int);
void freeMem(int *, int *, int *);
int main()
{
/* Dynamically allocated arrays to hold a list of numbers */
int *numList = nullptr;
int *frequency = nullptr;
int *modes = nullptr;
int numels = 0,
count = 0,
mode = 0;
cout << "\n\tMODE DISCOVERY PROGRAM\n\n"
<< "\tHow many elements should your set of numbers contain? ";
cin >> numels;
numList = new int[numels];
frequency = new int[numels]();
modes = new int[numels]();
/* Gets a set of (pseudo)random numbers and stores them in numList */
getNumbers(numList, numels);
/* Sorts the numbers with an selection-sort algorithm */
sortNumbers(numList, numels);
/* Determines and stores the frequency of numbers found in numList */
getFrequency(numList, frequency, numels);
/* Sorts the elements in numList and frequency in descending order
using an dual-selection-sort algorithm */
dualSort(numList, frequency, numels);
/* Determines and returns the mode(s) or -1 if there is no mode */
mode = getMode(numList, frequency, modes, numels);
/* If the mode returned is not -1, the mode or modes are displayed */
if (mode != -1)
{
displayMode(modes, numels);
}
else
{
cout << "\n\tThis set of numbers does not contain any modes!";
}
/* Displays a histogram */
displayHistogram(numList, frequency, numels);
/* Frees the memory before the program exits */
freeMem(numList, frequency, modes);
pauseSystem();
return 0;
}
/* **********************************************************
Definition: getNumbers
This function accepts numList and numels as its arguments.
It creates a random list of numbers in the range from 1 to
15 and stores these in the numList.
********************************************************** */
void getNumbers(int *numList, int numels)
{
const int MIN_NUM = 1,
MAX_NUM = 15;
srand((unsigned int) time(NULL));
for (int index = 0; index < numels; index++)
{
*(numList + index) = (rand() % (MAX_NUM - MIN_NUM + 1) + MIN_NUM);
}
}
/* **********************************************************
Definition: sortNumbers
This function accepts numList and numels as its arguments.
It uses a selection-sort algorithm to sort the number in
ascending order.
********************************************************** */
void sortNumbers(int *numList, int numels)
{
int startScan = 0,
index = 0,
minIndex = 0,
minEl = 0;
for (startScan = 0; startScan < numels; startScan++)
{
minIndex = startScan;
minEl = *(numList + startScan);
for (index = startScan + 1; index < numels; index++)
{
if (*(numList + index) < minEl)
{
minEl = *(numList + index);
minIndex = index;
}
}
*(numList + minIndex) = *(numList + startScan);
*(numList + startScan) = minEl;
}
}
/* **********************************************************
Definition: getFrequency
This function accepts numList, frequency and numels as its
arguments. It counts the numbers stored in numList, totals
these numbers, and stores the sum-total in frequency.
********************************************************** */
void getFrequency(int *numList, int *frequency, int numels)
{
int total = 0,
count = 0;
/* Find numbers that are equal, and count these */
for (int index = 0; index < numels; index++)
{
total = 0;
count = 1;
while (*(numList + index) == *(numList + index + 1))
{
count++;
index++;
}
total = count;
*(frequency + index) = total;
}
}
/* **********************************************************
Definition: sortFrequency
This function accepts numList, frequency and numels as
arguments. It uses a dual-sort selection-sort algorithm to
sort numberList and frequency in descending order.
********************************************************** */
void dualSort(int *numList, int *frequency, int numels)
{
int startScan = 0,
index = 0,
maxIndex = 0,
tempList = 0,
maxEl = 0;
for (startScan = 0; startScan < numels; startScan++)
{
maxIndex = startScan;
maxEl = *(frequency + startScan);
tempList = *(numList + startScan);
for (index = startScan + 1; index < numels; index++)
{
if (*(frequency + index) > maxEl)
{
maxEl = *(frequency + index);
tempList = *(numList + index);
maxIndex = index;
}
}
*(frequency + maxIndex) = *(frequency + startScan);
*(numList + maxIndex) = *(numList + startScan);
*(frequency + startScan) = maxEl;
*(numList + startScan) = tempList;
}
}
/* **********************************************************
Definition: getMode
This function accepts numList, frequency, modes, and
numels as arguments. First the function determines whether
there are numbers more frequent than any other, modes gets
this number. If there is no mode, -1 is returned.
********************************************************** */
int getMode(int *numList, int *frequency, int *modes, int numels)
{
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 (*(numList + index) == *(numList + index + 1) ||
*(frequency + index) == 1)
{
mode = -1;
}
for (int index = 0; index < numels; index++)
{
if (*(frequency + index) > frHigh)
{
frHigh = *(frequency + index);
}
if (frHigh == *(frequency + index))
{
*(modes + index) = *(numList + index);
}
}
return mode;
}
/* **********************************************************
Definition: displayMode
This function accepts modes, mode and numels as arguments.
It displays the mode or modes found in the numList array.
If no mode has been found, a message is displayed.
********************************************************** */
void displayMode(int *modes, int numels)
{
cout << "\n\n\tMODES\n\n"
<< "\tThese mode(s) have been discovered: \n\n";
for (int index = 0; index < numels; index++)
{
if (*(modes + index) > 0)
{
cout << "\tMode #" << (index + 1) << setw(14) << right
<< *(modes + index) << " \n";
}
}
}
/* **********************************************************
Definition: displayHistogram
This function accepts numList, frequency and numels as
arguments. It displays all numbers in numList, sorted in
order from highest to lowest, the frequency, and of occurence.
********************************************************** */
void displayHistogram(int *numList, int *frequency, int numels)
{
int index = 0,
total = 0,
count = 0;
cout << "\n\t\n\tHISTOGRAM\n\n"
<< "\tNUMBERS: " << setw(17) << right
<< "FREQUENCY:" << setw(17) << right
<< "HISTOGRAM:\n";
cout << "\t-------" << setw(18) << right
<< "---------" << setw(17) << right
<< "---------\n";
for (index = 0; index < numels; index++)
{
total = 0;
if (*(frequency + index) > 0)
{
total = *(frequency + index);
cout << setw(11) << right << *(numList + index)
<< setw(15) << right << *(frequency + index)
<< setw(15) << right;
for (count = 1; count <= total; ++count)
{
cout << "*";
}
cout << "\n";
}
}
}
/* **********************************************************
Definition: freeMem
This function accepts numList, frequencies and multiMode
as its arguments. It frees the memory before the program
exits.
********************************************************** */
void freeMem(int *numList, int *frequency, int *modes)
{
delete[] numList;
delete[] frequency;
delete[] modes;
numList = nullptr;
frequency = nullptr;
modes = nullptr;
}
Example Output:
Subscribe to:
Posts (Atom)














