/* 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;
}
No comments:
Post a Comment