#include <iostream>
#include <iomanip>
#include <string>
#include <time.h>
usingnamespace std;
int main()
{
int* Num_students;// to dynamically allocate an array
int Num_students_surveyed;//number of student surveyed
int count;//counter variable in the loop
int total;//to calculate the total of movies watched
double mode;
double average;//to calculate the average
double median;//Calculate the median of movies watched
//Ask about the number of students surveyed
cout << "How many student are surveyed?" << endl;
cin >> Num_students_surveyed;
//Dynamically allocate an array large enough to hold the number of student surveyed
Num_students = newint[Num_students_surveyed];
cout << endl;
cout << "______________________________________________________________________" << endl;
//Get the number of movies watched by each student
cout << "How many movies did each of the students watch ? " << endl;
for (count = 0; count < Num_students_surveyed; count++)
{
cout << "Student#" << count + 1 << ": ";
cin >> Num_students[count];
}
//Calculate the totale of movies watched
total = Num_students[count];
//Calculate the average of movies watched
average = total / Num_students_surveyed;
//Show the total and averaged of movies watched
{
cout << "The mode of movies watched is:" << total << " movies." << endl;
}
{
cout << "The Average of movies watched is:" << average << "movie." << endl;
}
//Calcullate and show the median of movies watched
median = total / 2;
{
cout << "The median of movies watched is:" << median << "movies." << endl;
}
//Free dynamically allocated memory
delete[] Num_students;
Num_students = 0; //Make the rest of unused arrays NULL
return 0;
}
start here:
total = Num_students[count]; what does this do? I don't think this does what you think it does.
//it goes out of bounds, potentially, as count was incremented one last time to exit the loop.
//and its not the total, its one item, if it were a valid location
consider: total up the values as they are input by user? change the above to += and put it inside the loop.
average = total / Num_students_surveyed; //this only works if total is correct. also, do you understand integer division vs floating point result? you need to cast one of those as a double if you want the double result. If you want the int result, average's type is wrong.
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <time.h>
usingnamespace std;
// Function prototypes
double retrieveMean(int*, int);
double calculateMedian(int*, int);
int calculateMode(int*, int);
int main()
{
cout << " *Movie Statistics Program*\n\n";
cout << "_______________________________________________________________/" << endl;
int* nums; // dynamically allocated array
int num_students; // To hold the number of students
char repeat = ' ';
//Do while loop to get number of students and also to warn a user if they enter a number less than 0
do
{
// user enters how many students were surveyed
cout << "How many students were surveyed? : ";
cin >> num_students;
while (num_students < 0)
{
cout << "Invalid number of students!\n";
cout << "Enter in how many students were surveyed: ";
cin >> num_students;
}
// Dynamically array to hold number of students asked
nums = newint[num_students];
// for loop to get the number of movies seen by each student asked in the survey.
for (int count = 0; count < num_students; count++)
{
cout << "Number of movies seen by student #" << (count + 1) << ": ";
cin >> nums[count];
// Determine input validation.
while (nums[count] < 0)
{
cout << "Enter a number higher than zero: ";
cout << "\nNumber of movies seen by student #" << (count + 1) << ": ";
cin >> nums[count];
}
}
// Just adds spacing and title of report for the output of median, mean, and mode
cout << endl;
cout << endl;
cout << endl;
cout << " *Movie Statistcs Report of Mean, Median, and mode* " << endl;
cout << "____________________________________________________________________________________" << endl;
// set decimals points to 2 places
cout << fixed << showpoint << setprecision(2);
// outputs the mean
cout << "The mean is: ";
cout << retrieveMean(nums, num_students) << endl;
// outputs the median
cout << "The median is: ";
cout << calculateMedian(nums, num_students) << endl;
// outputs the mode
cout << "The mode is: ";
cout << calculateMode(nums, num_students) << endl;
// frees up memory
delete[] nums;
nums = 0;
// while loop to start over or end survey
cout << "Do you want to start this survey over? ";
cin >> repeat;
} while (repeat == 'Y' || repeat == 'y');
cout << " Have a great day then ! \n";
return 0;
}
gets//mean
double retrieveMean(int* nums, int num_students)
{
double total = 0;
double average_num;
for (int count = 0; count < num_students; count++)
{
total += nums[count];
}
average_num = total / num_students;
return average_num;
}
//gets median
double calculateMedian(int* nums, int num_students)
{
double median = 0.0;
cout << fixed << showpoint << setprecision(2);
if (num_students % 2 == 0)
{
median = (nums[num_students / 2] + nums[(num_students / 2) + 1]) / 2.0;
}
else
median = nums[num_students / 2];
return median;
}
//gets mode
int calculateMode(int* nums, int num_students)
{
int mode = 0;
int val = 0;
int index;
for (index = 0; index < num_students; index++)
{
if (*(nums + index) == *(nums + (index + 1)))
{
mode++;
val = *(nums + index);
}
}
if (val > 0)
return val;
elsereturn -1;
}
You are using pointer syntax unnecessarily, you can just use array syntax like you do in calculateMedian/""Mean. e.g. instead of *(nums + index), just do: nums[index].
#include <iostream>
#include <string>
// BAD
int calculateMode(int* nums, int num_students)
{
int mode = 0;
int val = 0;
int index;
for (index = 0; index < num_students; index++)
{
if (*(nums + index) == *(nums + (index + 1)))
{
mode++;
val = *(nums + index);
}
}
if (val > 0)
return val;
elsereturn -1;
}
bool Test_calculateMode()
{
int nums[] = {3, 5, 5, 5, 3, 4, 4};
return (calculateMode(nums, 7) == 5);
}int main()
{
if (Test_calculateMode())
{
std::cout << "Passed\n";
}
else
{
std::cout << "Failed\n";
}
}
If you run this, you'll see the test fails. Why did it fail? Try going through the logic line by line to see. The crux of the issue is that you're (1) going out of bounds by doing nums[index + 1] (your post's line 133), but also (2) you are only keeping track of the last set of repeating numbers, not number of total occurrences of each number.
One option is, if you're allowed to manipulate the array while measuring it, would be to sort the array and then find the largest streak. (Copy the arrays elements into a temporary array if you're not allowed to re-order the elements)
This is the second time you've gone out of bounds (jonnin mentioned a previous instance of doing so). Be extra careful here. An easy check is saying "what is the largest value that index can be", and then seeing if the input into an array[some_index] is larger than that.
So what should I be doing ? I’m a beginner and you’re explaining advanced concepts that I don’t fully understand.
Can you break it down what I should be doing first to get an accurate mode
Most of my post was to show an example of a test that answers your previous question of "is my mode calculation right?".
Break it down like this:
1. You have an array of numbers, e.g. {5, 3, 5, 5, 3, 6, 4, 4, 6}
2. Sort the array so that the numbers are in ascending order: e.g. {3, 3, 4, 4, 5, 5, 5, 6, 6};
3. Find the longest "streak" of the same number in the data. This is now possible because the data is sorted. e.g. the longest streak here is 5. That is the mode.
There might be other ways to find the mode without sorting the data... but they would make things more complicated, imo. (edit: as dhayden showed, not necessarily more complicated, although sorting might be more efficient for large data sets)
int
calculateMode(int *nums, int num_students)
{
unsigned bestIdx=0; // Index of a number with the highest frequency seen so far
unsigned bestCount=1; // number of items in the highest frequency seen so far
unsigned curCount = 1; // number of times the current value has been seen
for (each item, starting with the second one, not the first) {
if (the current item is the same as the one before it) {
// There are multiple occurrences of this item
increment curCount
} else {
// This item is different from the previous one. If the previous item occurred
// more times than the best one so far, then it becomes the new best one
if (curCount > best Count) {
bestCount = curCount;
bestIdx = i - 1; // the index of one of the items with the count.
}
curCount = 1; // and indicate that this item has occurred once so far.
}
// When you get to the end of the loop, bestCount and bestIdx reflect the
// most frequent item *unless* the most frequent item is the last one in the list
// In that case we haven't checked it yet, so do it now
if (curCount > bestCount) {
bestCount = curCount;
bestIdx = num_students-1;
}
// Now bestCount and bestIdx reflect the most frequent item.
// You need to return the value. That's why we've been keeping track of bestIdx
// all this time - it's the index of one of the items that appears most frequently
return nums[bestIdx];
}