Reputation: 61
I have been assigned to set up an array with points. I am told to get the maximum value, average, and within this same array, if any point in the array is twice the average, I should cout
an "outlier." So far I have gotten the average and maximum numbers in the array. but i am unable to set the programme to cout
the outlier. Instead it gives me a multiple of the average.
here is the programme;
int main()
{
const int max = 10;
int ary[max]={4, 32, 9, 7, 14, 12, 13, 17, 19, 18};
int i,maxv;
double out,sum=0;
double av;
maxv= ary[0];
for(i=0; i<max; i++)
{
if(maxv<ary[i])
maxv= ary[i];
}
cout<<"maximum value: "<<maxv<<endl;
for(i=0; i<max; i++)
{
sum = sum + ary[i];
av = sum / max;
}
cout<<"average: "<<av<<endl;
out = av * 2;
if(ary[i]>out)
{
cout<<"outlier: "<<maxv<<endl;
}
else
{
cout<<"ok"<<endl;
}
return 0;
}
Upvotes: 6
Views: 349
Reputation: 42082
I prepared the following program (mostly for my own learning). It attempts to make as much use of the C++ Standard Library as possible.
#include<iostream>
#include<iterator>
#include<vector>
#include<algorithm>
int main() {
std::vector<float> nums;
// this will read the numbers from standard input; it will continue
// for as long as it can read floats (to stop you can enter a
// letter, or press Ctrl+D)
std::copy(std::istream_iterator<float>(std::cin),
std::istream_iterator<float>(),
std::back_insert_iterator<std::vector<float>>(nums));
// calculate the mean
float mean = std::accumulate(nums.begin(), nums.end(), 0) / nums.size();
std::cout<<"Mean of "<<nums.size()<<" numbers: "<<mean<<std::endl;
// create a lambda function which returns true if a number is BELOW
// twice the mean
auto fun = [&mean](float x) {return x < 2.0 * mean;};
// partition the list of numbers: those for which the lambda is true
// (i.e., the ones BELOW twice the man) will come before the
// outliers; the stable sort ensures that within each partition the
// numbers come in the original order
auto mark = std::stable_partition(nums.begin(), nums.end(), fun);
// mark gives an iterator to the first element of the second
// partition; it it is before the end we report the outliers
if(mark!=nums.end()) {
std::cout<<"Found "<<nums.end()-mark<<" outliers:"<<std::endl;
for(auto it=mark; it!=nums.end(); ++it) {
std::cout<<"\t"<<*it<<std::endl;
}
} else {
std::cout<<"No outliers found."<<std::endl;
}
return 0;
}
My output (compiled with g++
(GCC 4.7.2) using the -std=c++11
flag).
[Prompt] ./a.out
1 2 3 4 5 20 f # the f is to end the stream of numbers; press enter
Mean of 6 numbers: 5
Found 1 outliers:
20
Upvotes: 0
Reputation: 263138
Here is a C++ solution to your assignment, but you probably won't be allowed to hand that in ;-)
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <numeric>
int main()
{
const int N = 10;
int ary[N] = {4, 32, 9, 7, 14, 12, 13, 17, 19, 18};
int max = *std::max_element(ary, ary + N);
std::cout << "maximum: " << max << std::endl;
double average = std::accumulate(ary, ary + N, 0.0) / N;
std::cout << "average: " << average << std::endl;
std::cout << "outlier: ";
std::remove_copy_if(ary, ary + N,
std::ostream_iterator<int>(std::cout, " "),
std::bind2nd(std::less_equal<double>(), 2 * average));
std::cout << std::endl;
}
Upvotes: 4
Reputation: 4028
Your code contains a subtle and tricky to spot bug. You're using ary[i] after the final for loop. At this point, the value of i is equal to max, so your if statement is comparing random memory because you're going off the end of the array.
Since this is C++ and not C, you could have avoided this particular bug by declaring your loop variables in the for loop like this
for (int i = 0; i < max; ++i) {
....
}
Upvotes: 10
Reputation: 19181
If it is exactly twice the average it should be '==' instead of bigger then twice the avarage.
Aslo why are you outputing maxv
? Try to use more meaningful names.
Shouldn't you print ary[i]
instead?
Also, why aren't you looping the array again with a for loop? Shouldn't you iterate all over it to find all outliners or should only the last element be checked for an outliner.
Upvotes: 0
Reputation: 49166
You'll need to use two for-loops. You should be traversing the ary
and checking each element against out
, then cout << ary[i]
.
This would probably be a little more obvious if you declared your variables where they are used, in the smallest scope possible.
For example:
for (int i = 0; ...) {
}
and
double outlier = avg * 2;
By the way, this may be a little over-your-head (right now), but STL provides functions for determining the max
(max_element) and sum
(accumulate) of an array. It might be interesting reading.
Upvotes: 0