Using a function to find the average of an array C++ - c++

the purpose of this task is to find the average of an array but not within the main, I have to call a function to do the sum and show the average.
I though my code was sound but it just returns " the average is 011014F1"
I have tried a few different ways of doing the function but I've gone wrong somewhere, maybe everywhere!
Just a heads up, im just starting out with programing.
Heres my code:
#include <iostream>
#include <vector>
using namespace std;
void printArray(int theArray[], int sizeOfarray);
float average(float numbers[], float size, float arrayAverage);
int main()
{
int array[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
printArray(array, 10);
cout << "The average is: " << average << endl;
return 0;
}
void printArray(int theArray[], int sizeOfarray)
{
for (int x = 0; x < sizeOfarray; x++)
{
cout << theArray[x] << endl;
}
}
float average(float numbers[], float size, float arrayAverage)
{
double sum = 0.0;
for (int x = 0; x < size; x++)
{
sum += numbers[x];
arrayAverage = sum / size;
}
return (arrayAverage);
}
I had the float average function initially set as a float with int for 'numbers', 'size' and 'arrayAverage' but thought i would change them all to float so they dont clash. like converting an int to a float etc..
As i said im new to this so my logic is not really there but i think im n the right tracks.
Any idea why its returning 011014F1 and numbers like that instead of just the average of 1-10?
Any tips much appreciated!

average is a function, which you need to call, and print what it returns. What you are printing now is the address of that function.

There are a number of problems here. First:
cout << "The average is: " << average << endl;
This is simply printing out the address of the average function, not calling it. What you wanted to do was:
cout << "The average is: " << average(array, 10, 0) << endl;
Second, your method signature has all kinds of type missmatches. The expected array value type is float, yet you're passing it an array of int. This won't work, as the compiler will not allow the implicit conversion from int[] to float[]. Your size argument should be an int in the method signature as well, not float, since array sizes are always integers.
Third, the arrayAverage parameter seems to have no purpose except to possibly throw off your math. You use it as a running accumulator, which is fine, but there's no reason to pass it to the function, it could just be a local value. So, your method signature should look like this:
float average(float numbers[], int size);
Finally, your math for calulating the average of an array is wrong. You do:
for (int x = 0; x < size; x++)
{
sum += numbers[x];
arrayAverage = sum / size;
}
Particularly, the arrayAverage = sum / size is wrong. Or rather, is only right during the final loop iteration. Meaning this is just wasted math. It should be:
float average(float numbers[], int size) {
double sum = 0;
for (int x = 0; x < size; x++)
{
sum += numbers[x];
}
return sum /(double)size;
}

You are not passing any thing to your function average, float average(float numbers[], float size, float arrayAverage)You should pass your array as first parameter and the size of the array in the second, the third one you dont need it , I recommand you to delete itYour function will be :
float average(float numbers[], float size)
{
float average;
double sum = 0.0;
for (int x = 0; x < size; x++)
{
sum += numbers[x];
arrayAverage = sum / size;
}
return (average);
}
and in your main you do a float averageResult = average(array, size);
qDebug()《 averageResult;

#include <iostream>
#include <vector>
using namespace std;
void printArray(int theArray[], int sizeOfarray);
int main()
{
int array[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
printArray(array, 10);
return 0;
}
void printArray(int theArray[], int sizeOfarray)
{
for (int x = 0; x < len(theArray); x++)
{
average = average + theArray[x]
}
average = average/(len(theArray));
cout << average;
}

Related

How many numbers higher than average [C++]

I filled an array with 30 random numbers and calculated average. I want to display how many numbers are higher than the average. I tried making a function "aboveAverage" and check if the numbers are higher than the average and than just increase the count "num_over_average++". The problem is I don't know how to pass a value "avg" from function to another function.
#include <iostream>
#include <ctime>
using namespace std;
const int n = 30;
void fillArray(int age[], int n) {
srand(time(NULL));
for (int index = 0; index < n; index++) {
age[index] = (rand() % 81) + 8;
}
}
void printArray(int age[], int n) {
for (int index = 0; index < n; index++) {
cout << age[index] << endl;
}
}
double printAverage(int age[], int n) {
double sum;
double avg = 0.0;
for (int i = 0; i < n; i++) {
sum = sum + age[i];
}
avg = ((double) sum) / n;
cout << avg << endl;
return avg;
}
void aboveAverage(int age[], int n) {
double avg;
int num_over_average = 0;
for(int i = 0; i < n; i++){
if(age[i] > avg) {
num_over_average++;
}
}
cout<<num_over_average;
}
int main(int argc, char *argv[]) {
int age[n];
fillArray(age, n);
cout << "array: " << endl;
printArray(age, n);
cout << endl;
aboveAverage(age, n);
//example: Days above average: 16
}
This should be a comment, but I don't have enough reps :(
Change aboveAverage to void aboveAverage(int age[], int n, double avg)
Return avg from printAverage function
Change the last part of your main code to
double avg;
avg = printAverage(age, n);
aboveAverage(age, n, avg);
Hope this helps!
You have two solutions using your code:
Either you call printAverage() to initialise avg in aboveAverage() :
void aboveAverage(int age[], int n) {
double avg = printAverage();
...
}
Or you pass the average at parameter of aboveAverage() after having computed it with printAverage() :
void aboveAverage(int age[], int n, double avg) {
...
}
If you use the standard library you can do that with two lines of code:
double average = std::accumulate(std::begin(age), std::end(age), 0.0) / std::size(age);
int above_average = std::count_if(std::begin(age), std::end(age),
[average](double value) { return average < value; });
Okay, you might count that as three lines.
One major advantage of this approach over the code in the question is that you can change the container type to, say, vector<double> without having to change any of this code.
Well is pretty simple but dependent on your situation, I'll elaborate.
I'm the case when it's part of a bigger function (do-somthing())
You could calculate the average value like so and pass it to your "aboveAverage" function and print it:
double n_average = printAverage(nArr_ages, n_agesArraySize);
aboveAverage(nArr_ages, n_agesArraySize, n_averag);
Myself would probably rewrite the printAverage function as two functions, one that returns the average value based on the array and another that prints it not both at once because it violates the SOLID principals of a single responsibility and that a function name should reflect exactly what it does, in this case maybe calculateAverage or getAverageAge or any other appropriate name will do (try and name your functions like the english language so your code will be read like a song.
For example:
const size_t n = 30;
double calculateAverage(int nArr_ages[], int n_agesArraySize) {
double sum = 0.0;
double avg = 0.0;
for (int indexInArray = 0; indexInArray < n_agesArraySize; indexInArray++) {
sum = sum + age[indexInArray];
}
average = ((double) sum) / n_agesArraySize;
return average;
}
int aboveAverageCells(int ages[], int n_agesArraySize ) {
double average = calculateAverage(ages, n);
int num_over_average = 0;
for(int indexInArray = 0; indexInArray < n_agesArraySize; indexInArray++) {
if(ages[indexInArray] > avg) {
num_over_average++;
}
}
return num_over_average;
}
Now just call them in order, save the returned values to local variables in the main function and print using cout also locally in main.
As a side note next time maybe choose different names for the const and the local functions variable for the array size.

Converting Array of type float to doubles

I really need help on learning how to convert arrays of different types to doubles (short, long, float). I'm not really sure how to ask the question any better. This is for an assignment for school. I understand that the assignment isn't complete, I just need to learn to do this before I continue to make arrays for short and long types.
Assignment Description:
We are going to expand program to account for different primitives. This implementation will implement all 8 functions described in program 2 as templates. To show this works, the main function will declare 4 different arrays that contain 10 values. The different arrays will be declared as shorts, longs, floats, and doubles. Each array will be filled with random values from a random-number generator. The array will be printed, then each of the 8 functions will be called and the results printed to the user. In order to provide a container, each of the functions will be part of a class called “MathHelper” that has all of the functions declared with a public access modifier and a static modifier.
MathHelper.h
#pragma once
class MathHelper
{
public:
static double calculateSum(const double numbers[], const int& count);
static double calculateAverage(const double numbers[], const int& count);
static int highestNum(const double numbers[], const int& count);
//int lowestNum(const int numbers[], const int& count);
//int numRange(const int numbers[], const int& count);
//double standardDeviation(const int numbers[], const int& count);
//int smallestFactorial(const int numbers[], const int& count);
};
MathHelper.cpp
#include "MathHelper.h"
MathHelper::MathHelper()
{
}
double MathHelper::calculateSum(const double numbers[], const int& count)
{
if (count <= 0)
return 0;
double total = 0;
for (int i = 0; i < count; i++)
total += numbers[i];
return total;
}
double MathHelper::calculateAverage(const double numbers[], const int& count)
{
if (count <= 0)
return 0;
return static_cast<double>(calculateSum(numbers, count)) / count;
}
int MathHelper::highestNum(const double numbers[], const int& count)
{
if (count <= 0)
return 0;
int highest = numbers[0];
for (int i = 1; i < count; ++i)
if (highest < numbers[i])
highest = numbers[i];
return highest;
}
MathHelper::~MathHelper()
{
}
Program4.cpp
// Program4Fix.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "MathHelper.h"
#include <iostream>
#include <cmath>
#include <ctime>
#include <iomanip>
int main()
{
const int size = 10;
double* myDoubles = new double[size];
float* myFloats = new double[size];
srand((unsigned)time(NULL));
// double fill
std::cout << std::endl;
std::cout << "Double Array: \n";
for (int i = 0; i < size; i++)
{
*(myDoubles + i) = rand() / double(RAND_MAX)*50.f + 1.f;
std::cout << i << ": " << std::setprecision(4) << *(myDoubles + i) << std::endl;
}
std::cout << std::setprecision(5) << "The sum of the numbers is: " << MathHelper::calculateSum(myDoubles, size) << "\n";
std::cout << std::setprecision(5) << "The average of the numbers is: " << MathHelper::calculateAverage(myDoubles, size) << "\n";
// long fill
std::cout << "Float Array: \n";
for (int i = 0; i < size; i++)
{
*(myFloats + i) = rand() / float(RAND_MAX)*50.f + 1.f;
std::cout << i << ": " << std::setprecision(4) << *(myFloats + i) << std::endl;
}
std::cout << std::setprecision(5) << "The sum of the numbers is: " << MathHelper::calculateSum(myFloats, size) << "\n";
std::cout << std::setprecision(5) << "The average of the numbers is: " << MathHelper::calculateAverage(myFloats, size) << "\n";
return 0;
}
I guess my real question is, is there anyway to use a value of type double* to initialize an entity of type float*?
const int size = 10;
double* myDoubles = new double[size]; // this works
float* myFloats = new double[size]; // this doesn't work, is there a way to do this similar to the one above?
Since you are asking about C++, don't use implicit conversion
double d = 1.5;
int i = d;
Also don't use c-style casting:
double d = 1.5;
int i = (int)d;
Make use of proper casting
int i = static_cast<int>(d);
You can read up on why, there are many reasons why to cast in C++.
For converting the array, you need to create a new array and then iterate over the existing one, convert one by one and then assign them to the new one.
For C++11 you can possibly use the std::transform() function.
I guess what you should do is generalize the functions in MathHelper to template functions which can be used for other types than double. I would get a decent C++ book and read about template functions, e.g. in A Tour of C++ or Programming -- Principles and Practice Using C++. You can get the first four chapters for the Tour of C++ from isocpp.org, and the second chapter introduces templates.
In the end, you should have code that looks like
class MathHelper
{
public:
template<typename T> static double calculateSum(const T numbers[], const int& count);
};
As a general remark, the posted code looks very C-ish meaning that it uses C-constructs where C++ has better alternatives, e.g. manually managed arrays instead of std::vector. You should avoid this.
Converting to double from float, int, or long is as simple as just assigning the source variable to a variable declared double.
For example:
int a = 1
long b = 2;
float c = 3.0f;
double result;
result = a;
result = b;
result = c;
In the 3 last statements, the values will be converted to doubles for you.
You can also convert the other way by casting.
const int size = 10;
double* myDoubles = new double[size];
float* myFloats = new float[size];
InitializeArray(myDoubles); // You'll have to start with some values
for(int i = 0; size > i; ++i)
{
myFloats[i] = (float) myDoubles[i];
}

Calculate average from an array

I tried to calculate average and when I enter 1 2 3 0 , the average is 2.00 but when I enter 10 20 90 100 0,the average is 227871776.00. I am not able to identify what is going wrong here. I feel like my sum and count is not working properly but I can't figure out why.
double calculateAverage(int numbers[], int count )
{
int sum = 0;
double average;
while (count < arraysize && numbers[count] != 0)
{
count ++;
}
for (int i= 0 ; i < count; i++)
{
sum += numbers[i];
}
average = static_cast<double>(sum) /count;
return average;
}
Why bother even making your own count loop, when you have std:accumulate.
#include <numeric>
#include <iostream>
double calculateAverage(int numbers[], size_t count)
{
int sum = std::accumulate(numbers, numbers + count, 0);
return sum / count;
}
int main()
{
//int numbers[] = {1, 2, 3, 4, 5};
int numbers[] = {10, 20, 90, 100};
std::cout << "average is " <<
calculateAverage(numbers, sizeof(numbers) / sizeof(int)) << '\n';
}
Your code was quite confused. Why pass a count if you're going to count the array anyway? Also 0 is a valid value in the array and so it makes a flawed sentinel value.
#include<iostream>
using namespace std;
double calculateAverage(int numbers[], int count )
{
int sum = 0; //sum is used to add all the values in the array
double average;
for (int i= 0 ; i < count; i++)
sum += numbers[i];
average = static_cast<double>(sum) /count;
return average;
}
int main()
{
int lim; //size of the array
cout<<"Enter the number of elements in array\n";
cin>>lim;
cout<<"Enter the values \n";
int num[lim]; //the array is initialized to desired size
for(int i=0;i<lim;i++)
cin>>num[i]; //the values are taken from user
cout<<"\nAverage = "<<calculateAverage(num,lim)<<"\n"; //the array and the size of array is passed to calculate average function or you can even calculate size of array using (sizeof(array)/sizeof(array[firstelement])
return 0;
}
Recreate the code overall
It is hard to understand (your code).
Mine:
double calculateAverage(double numbers[], double count )
{
double sum = 0;
double average=0;
for(int counter=0;counter<count;counter++)
{
sum+=numbers[counter];
}
cout<<sum<<"\n";
average=sum/count;
return average;
}
Explaination:
First the function will take an array of double
and count is how many is there in the array (I tried to stick into your code)
The for loop runs based on the count variable.
the sum adds the value of the element in the array numbers.
Divide to get the average.
numbers[count] != 0 could produce errors when you have 0 appear earlier in the array. Also, where do you initialize arraysize? It could be null somehow or a very weird number. I recommend calling the numbers length instead. But there's no reason to use the while loop bc you have an array size already known

Calculating average then returning the closest element in array to the average

I suppose to calculate the average in the array of doubles then return the value of the closest element in the array to the calculated average. But the algorithm I used is O(2n). Is it possible to determine the closest element to the average while still calculating average?
I think no.
#include <iostream>
#include <cmath>
using namespace std;
double* aver(double* arr, size_t size, double& average){
for(int i = 0; i < size; i++)
average+=arr[i];
average/=size;
double* ret = arr;
for(int i = 0; i < size; i++){
if(abs(arr[i] - average) < abs(*ret - average)){
*ret = arr[i];
}
}
return ret;
}
int main(){
double arr[] = {1,2,3,4,5,7};
size_t size = sizeof(arr)/sizeof(arr[0]);
double average = 0;
double* p = aver(arr, size, average);
cout<< *p << " " << average << endl;
return 0;
}
You can find an element closest to a target with a trivial O(logn) binary search if the array is sorted. If it's not sorted, then it's a linear search.
As a side note, O(2n) might make intuitive sense, but mathematically speaking it's no different than O(n).
Under the premise of exclusively non-negative values in the array, you might use this adaption of your code:
#include <iostream>
#include <cmath>
using namespace std;
double* aver(double* arr, size_t size, double& average){
int iclosest = 0;
for(int i = 0; i < size; i++) {
average+=arr[i];
if (abs(arr[iclosest + 1] - average/(i+1)) < abs(arr[iclosest] - average/(i+1)))
++iclosest;
}
average/=size;
return &arr[iclosest];
}
int main(){
//double arr[] = {1,2,3,4,5,7};
double arr[] = {4,5,3,2,1,7};
size_t size = sizeof(arr)/sizeof(arr[0]);
double average = 0;
double* p = aver(arr, size, average);
cout<< *p << " " << average << endl;
return 0;
}
It can be adapted to work with negative values, either.
But that said, I concur with Blindy as far as O(2n) = O(n) is concerned.

Checking which of the modules is the closest

Welcome. My problem is that I have given an array of numbers which I need to calculate the average (that part I did), but then I have to find the array element (module), which is closer to the average. Below paste the code (a form of main () imposed)
#include <iostream>
using namespace std;
double* aver(double* arr, size_t size, double& average){
double count;
for(int p = 0; p < size; p++)
count += arr[p];
count /= size;
double * pointer;
pointer = &count;
average = *pointer;
}
int main() {
double arr[] = {1,2,3,4,5,7};
size_t size = sizeof(arr)/sizeof(arr[0]);
double average = 0;
double* p = aver(arr,size,average);
cout << p << " " << average << endl;
}
The program should give a result
4 3.66667
I have no idea how to check which element is nearest to another, and substitute it into *p
I will be very grateful for any help.
Okay, this is not the answer to your problem, since you already got couple of them
How about trying something new ?
Use std::accumulate, std::sort and std::partition to achieve same goal.
#include<algorithm>
//...
struct comp
{
double avg;
comp(double x):avg(x){}
bool operator()(const double &x) const
{
return x < avg;
}
};
std::sort(arr,arr+size);
average =std::accumulate(arr, arr+size, 0.0) / size;
double *p= std::partition(arr, arr+size, comp(average));
std::cout<<"Average :"<<average <<" Closest : "<<*p<<std::endl;
This algorithm is based on the fact that std::map keeps its elements sorted (using operator<):
#include <map>
#include <iostream>
#include <math.h>
using namespace std;
double closest_to_avg(double* arr, size_t size, double avg) {
std::map<double,double> disturbances;
for(int p = 0; p < size; p++) {
disturbances[fabs(avg-arr[p])]=arr[p]; //if two elements are equally
} //distant from avg we take
return disturbances.begin()->second; //a new one
}
Since everybody is doing the kids homework...
#include <iostream>
using namespace std;
double min(double first, double second){
return first < second ? first : second;
}
double abs(double first){
return 0 < first ? first : -first;
}
double* aver(double* arr, size_t size, double& average){
double count;
for(int p = 0; p < size; p++)
count += arr[p];
average = count/size;
int closest_index = 0;
for(int p = 0; p < size; p++)
if( abs(arr[p] - average) <
abs(arr[closest_index] - average) )
closest_index = p;
return &arr[closest_index];
}
int main() {
double arr[] = {1,2,3,4,5,7};
size_t size = sizeof(arr)/sizeof(arr[0]);
double average = 0;
double* p = aver(arr,size,average);
cout << *p << " " << average << endl;
//Above ^^ gives the expected behavior,
//Without it you'll get nothing but random memory
}
I insist that you need the * before the p, it gives the value that the pointer is pointing too. Without the * then the value is the address of the memory location, which is indeterminate in this case. Ask your professor/teacher whether the specification is correct, because it isn't.
Try and understand the style and functions involved - it isn't complicated, and writing like this can go a long ways to making your graders job easier.
Also that interface is a very leaky one, in real work - consider some of the standard library algorithms and containers instead.