0

I am extremely new to C++. I have some experience in Microsoft VBA but the syntax and how to find syntax for functions is much harder in C++.

I am trying to calculate the sum, average and count of numbers above average for an array. I was able to sum an array but ended up getting rid of it just to add the values up in order to create a set elsewhere to count numbers above the average. I am sure I am doing this all wrong but I was hoping some magic fairy would allow me to put set.count(>average) and magically work.


    #include <iostream>
    #include <bits/stdc++.h>
    #include <algorithm>
    using namespace std;

    int main()
    {

        //define four number value variables
        double number1, number2, number3, number4;

        //prompt user to input values for number variable
        std::cout << "Enter four double values: " << endl;
        std::cin >> number1 >> number2 >> number3 >> number4;

        //define array for use in expressions
        double arr[] = {number1, number2, number3, number4};

        //initialize set for use in expressions
        std::set<double> set(arr, arr + 4);

        //calculate sum and average and count
        double sum = number1 + number2 + number3 + number4;
        double average = sum / 4;
        double count = set.count(average);

        //output expressions
        std::cout << "The sum is: " << sum << endl
        << "The average is: " << average << endl
        << count << " numbers are above average." << endl;

        return 0;

    }

Saurabh P Bhandari
  • 6,014
  • 1
  • 19
  • 50
Doupis
  • 35
  • 7
  • `int count = std::count_if(set.begin(), set.end(), [average](double val) { return val > average; });` -- see https://en.cppreference.com/w/cpp/algorithm/count – paddy Oct 29 '19 at 02:40
  • 1
    Get rid of the array and the set. Use a `std::vector`. – super Oct 29 '19 at 02:41
  • 2
    `#include ` [loads the gun](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h). `using namespace std;` [takes the safety off](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). Be really cautious with this combination. – user4581301 Oct 29 '19 at 03:05
  • @user4581301 I'm self taught and know these things: I find your analogy very comical! – Francis Cugler Oct 29 '19 at 03:19
  • Unrelated: When you have sequentially numbered variables like `double number1, number2, number3, number4;` odds are really good that what you really need is an array. In the case of this code, that's proven a few lines later when the values are copied into an array. Often to compute sums and averages you don't need to store the individual numbers. Sum them up as you read them in and keep a count so you can divide the sum by the count to get the average later. – user4581301 Oct 29 '19 at 03:24
  • You don't need to use `std::` before every `cout` or `cin` or etc once you have already typed `using namespace std` you will need to use that if you didn't add any namespace or if added a user namespace – Blue Dice Oct 29 '19 at 04:22
  • 1
    @AruViser [That's actually not a good idea](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice). –  Oct 29 '19 at 04:24
  • It is considered bad practice to have `using namespace std;` in your code especially in the global namespace... – Francis Cugler Oct 29 '19 at 07:49

3 Answers3

3

With std::vector and accumulate from <numeric> this can be done quite simply. I even extended your problem above to allow the user to specify how many elements they want to find the sum, average and the instance count that is above the average.

Instead of declaring multiple variables I declared a single variable and just reused it and saved all of the values into a vector using a basic loop. Then I used accumulate to easily calculate the sum and used that result to calculate the average.

From there I used a range based for loop to check each element of the vector and to test if they were greater than the average that was calculated if so I incremented the occurrence variable. Finally I displayed all of the results.

I'm sure that this could be written a little cleaner and optimized but this is just a simple general solution to the task that you are trying to achieve.

#include <numeric>
#include <iostream>
#include <vector>

int main() {
    try {
        int num_values = 0;
        std::cout << "How many values would you like to enter? ";
        std::cin >> num_values;
        std::cout << "Enter each value\n";
        std::cin.ignore();

        double value = 0.0;
        std::vector<double> values;
        for (int i = 0; i < num_values; i++) {
            std::cin >> value;
            std::cin.ignore(); // I called this first so if it fails or throws an
                               // exception I save time by not calling push_back 
            values.push_back(value);
        }            

        auto sum = std::accumulate(values.begin(), values.end(), 0.0);
        auto avg = sum / values.size();

        int greater_than_average = 0;
        for (auto& v : values) {
            if (v > avg) greater_than_average++;
        }

        std::cout << "Sum = " << sum << "\nAverage = " << avg
            << "\nGreater Than Average = " << greater_than_average << '\n';

    } catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
Francis Cugler
  • 7,788
  • 2
  • 28
  • 59
0

You will need a new zero initialized variable, then use an IF sequence to solve your problem. Put the code below where you average.

int count_avg = 0;

// .. repeat this for all input numbers.
if (number1> average) {
count_avg = count_avg + 1;
}
if (number2> average) {
count_avg = count_avg + 1;
}
// ...

std::cout << count_avg << endl;

When you are more experienced, you can use a vector to store your entries and use a repeating structure to solve this same problem.

0

C++ is a compiled language. That means there are some things that are known at compile time and some things that are known are run time. The side effect of this is that when you try to mix them in certain ways, bad things can happen.

Let's take a close look at this line right here:

//define array for use in expressions
double arr[] = {number1, number2, number3, number4};

The size of the array arr has to be known at compile time. On the other hand, the values in number1,number2,number3, and number4 won't be known until run-time. While I'm not 100% certain that this shouldn't compile or run, I'd be scared to try. This is because things known at compile time and things that aren't known until run time are mixed at the same time.

The solution is surprisingly simple: just declare your array ahead of time. Then the changes to your code become a lot easier:

    double arr[4];
    //prompt user to input values for number variable
    std::cout << "Enter four double values: " << endl;
    std::cin >> arr[0]>> arr[1]>> arr[2]>> arr[3];

That's not pretty, but works. Perhaps it might be easier to write a loop instead:

    const unsigned int size = 4;
    double arr[size];
    //prompt user to input values for number variable
    std::cout << "Enter " << size << " double values: " << endl;
    for(unsigned int i=0; i<size;i++) {
        std::cin >> arr[i];
    }

Then you can change the size of your array quite easily. You could even replace most any constant that uses 4 to mean the size of the array to just size.


Edit: Ugh. Didn't quite go all the way. To average the numbers, you should be able to replace number variables with this instead:

double sum = arr[0] + arr[1] + arr[2] + arr[3];
double average = sum / 4;

Or you could construct a loop similar to the above loop to calculate it. I will leave the creation of such a loop as an exercise for you.