Reputation: 441
I am trying to write a program where the user inputs as many numbers as they want and then the program returns the average of the numbers. So far the program only outputs the last number entered.
#include <vector>
#include <iostream>
#include <numeric>
using namespace std;
int main()
{
vector<float> v;
int input;
cout << " Please enter numbers you want to find the mean of:" <<endl;
while (cin >> input);
v.push_back(input);
float average = accumulate( v.begin(), v.end(), 0.0/ v.size());
cout << "The average is" << average << endl;
return 0;
}
Upvotes: 24
Views: 135957
Reputation: 47814
In C++17 and higher, you should prefer std::reduce
over std::accumulate
. Both calculate the sum, but std::reduce
has higher numerical stability and, less importantly, is potentially faster because it might be parallelized.
#include <vector>
#include <numeric>
#include <iostream>
float average(std::vector<float> const& v){
if(v.empty()){
return 0;
}
auto const count = static_cast<float>(v.size());
return std::reduce(v.begin(), v.end()) / count;
}
int main(){
std::vector<float> v{8, 4, 2, 7, 5};
auto const a = average(v);
std::cout << "average: " << a << "\n";
}
Note that static_cast
suppresses a compile warning here, that std::size_t
(the type of v.size()
) with 8 byte size can theoretically express values for which the precision of a 4 byte float
is not sufficient.
Your code has two bug. First get rid of semi-colon after while
while (cin >> input); // <-- bug
v.push_back(input); // not in loop
// fixed loop
while (cin >> input){
v.push_back(input);
}
Second your average calculation is wrong. The third argument of std::accumulate
is the initial value of the sum, which is 0
by default, so you don't need to pass it.
Your actual bug is, that you divided the 0 by the element count. What you wanted, was to divide the value sum by the element count.
float average = accumulate(v.begin(), v.end(), 0.0 / v.size());
// ^^^^^^^^^^^^^^
// fixed code
float average = accumulate(v.begin(), v.end(), 0.0) / v.size();
// without explicit init value
float average = accumulate(v.begin(), v.end()) / v.size();
// C++17 version with higher numerical stability
float average = reduce(v.begin(), v.end()) / v.size();
Also, the element of container data type should match the container type or if your really want to read integers and add to a float
vector, you should use static_cast
. The bulky syntax not only suppresses any compiler warnings, but also makes it clear that this is not an oversight, but an intentional difference in data types.
vector<float> v; // float vector
int input; // integer input value
// ...
v.push_back(input); // add int value to float container
// an intentional type conversion should catch the eye
v.push_back(static_cast<float>(input));
Upvotes: 79
Reputation: 53
You can use vector_name.size() to get the number of elements in vector. Here's my attempt for to compute average:
#include <iostream>
#include <vector>
//function to compute average
double compute_average(std::vector<int> &vi) {
double sum = 0;
// iterate over all elements
for (int p:vi){
std::cout << "p is " << p << std::endl;
sum = sum + p;
}
return (sum/vi.size());
}
int main(){
std::vector <int>vi = {5,10};
double val;
val = compute_average(vi);
std::cout << "avg is " << val << std::endl;
return 0;
}
Upvotes: 0
Reputation: 409216
The third argument to std::accumulate
is the initial value, so you start with 0.0 / v.size()
(which is very small) and then add all items in the vector.
Instead you should use a value of zero as initial value, and after you calculated the total of all values in the vector then you divide by the size.
And as others pointed out, you only add the last value to the vector.
Upvotes: 2
Reputation: 5249
There are quite a few bugs in your code, have you actually debugged it? here's a working version:
#include <vector>
#include <iostream>
#include <numeric>
using namespace std;
int main()
{
vector<float> v;
float input;
cout << " Please enter numbers you want to find the mean of:" <<endl;
while (cin >> input)
v.push_back(input);
float average = accumulate( v.begin(), v.end(), 0.0)/v.size();
cout << "The average is" << average << endl;
return 0;
}
Upvotes: 13