Elements in array not changing

For my class I need to change the smallest and largest element in an integer array to 0, and then take all the numbers and find the average afterwards. For some reason I keep getting the average of all the numbers prior to the largest and smallest being changed to zero, that being 45.1. The actual average I'm suppose to be getting is 35.7. I think it has to do with replacing the elements in the array as printing the smallest and largest variable into cout gives me the values I'm looking to change in the first place.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include<iostream>
using namespace std; 
void myArray(int theArray[], int sizeofArray);
int main() {
	int input[10] = {85, 38, 77, 20, 28, 6, 70, 88, 12, 27};
	myArray(input, 10);
	system("Pause");
	return 0;
}

void myArray(int theArray[], int sizeofArray) {
	double average = 0, smallest = 999999, largest = 0;
	for (int a = 0; a < sizeofArray; a++) {
		//Finding the largest and smallest value
		if (theArray[a] < smallest) {
			smallest = theArray[a];
		}
		if (theArray[a] > largest) {
			largest = theArray[a];
		}
	}

	for (int a = 0; a < sizeofArray; a++) {
		//Replacing largest and smallest value
		if (smallest == theArray[a]) {
			theArray[a] = smallest;
		}
		if (largest == theArray[a]) {
			theArray[a] = largest;
		}
	}

	for (int a = 0; a < sizeofArray; a++) {
		//Adding the numbers in the array for the average
		average += theArray[a];
	}
	//Dividing for the average
	average = average / 10;
	cout << "The average of all the numbers is " << average << endl;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <algorithm> // std::minmax_element
#include <cmath> // NAN
#include <numeric> // std::accumulate

// replace one smallest and one largest element of the sequence with zeroes
void zero_minmax_elements( int array[], int sz ) {

    if( array == nullptr || sz < 1 ) return ;

    // https://en.cppreference.com/w/cpp/algorithm/minmax_element
    const auto [ psmallest, plargest ] = std::minmax_element( array, array+sz ) ;
    *psmallest = 0 ;
    *plargest = 0 ;
}

// return the average after setting one smallest element and
// one largest element of the array to zeroes
double zero_minmax_and_average( int array[], int sz ) {

    if( array == nullptr || sz < 1 ) return double(NAN) ;

    zero_minmax_elements( array, sz ) ;

    // https://en.cppreference.com/w/cpp/algorithm/accumulate
    return std::accumulate( array, array+sz, 0.0 ) / sz ;
}

void zero_minmax_elements_home_grown( int array[], int sz ) {

    if( array == nullptr || sz < 1 ) return ;

    int pos_min = 0 ;
    int pos_max = 0 ;
    for( int i = 1 ; i < sz ; ++i ) {

        if( array[i] < array[pos_min] ) pos_min = i ;
        if( array[pos_max] < array[i] ) pos_max = i ;
    }

    array[pos_min] = 0 ;
    array[pos_max] = 0 ;
}

double zero_minmax_and_average_home_grown( int array[], int sz ) {

    if( array == nullptr || sz < 1 ) return double(NAN) ;

    zero_minmax_elements_home_grown( array, sz ) ;

    double sum = 0 ;
    for( int i = 0 ; i < sz ; ++i ) sum += array[i] ;
    return sum / sz ;
}

int main() {

    const int N = 10 ;
    
    {
        int input[N] = { 85, 38, 77, 20, 28, 6, 70, 88, 12, 27 };
        std::cout << zero_minmax_and_average( input, N ) << '\n' ; // 35.7
    }

    {
        int input[N] = { 85, 38, 77, 20, 28, 6, 70, 88, 12, 27 };
        std::cout << zero_minmax_and_average_home_grown( input, N ) << '\n' ; // 35.7
    }
}

http://coliru.stacked-crooked.com/a/be443e5f1dfdb687
1
2
3
4
5
6
7
8
#include<iostream>
#include<valarray>
using namespace std; 
int main()
{
   valarray<int> input = { 85, 38, 77, 20, 28, 6, 70, 88, 12, 27 };
   cout << "Average with outliers set to zero (why not removed?) is " << ( input.sum() - input.min() - input.max() ) / (double)input.size();
}


Average with outliers set to zero (why not removed?) is 35.7
Average with outliers set to zero (why not removed?)

That is a good question. Lets emphasize it with an example:

{ 101, 102, 103 } has average: 102
{ 0, 102, 0 } has average: 34
{ 102 } has average: 102
One pass through the array is adequate.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <cmath>

// return the average after setting one smallest element and
// one largest element of the array to zeroes
double zero_minmax_and_average( int array[], int sz ) {

    if( array == nullptr || sz < 1 ) return double(NAN) ;
    
    // added: see keskiverto's post  
    if( sz == 1 ) return array[0] = 0 ;

    int pos_min = 0 ;
    int pos_max = 0 ;
    double sum = array[0] ;
    for( int i = 1 ; i < sz ; ++i ) { // just one pass through the array

        if( array[i] < array[pos_min] ) pos_min = i ;
        
        // if( array[pos_max] < array[i] ) pos_max = i ;
        // to take care of another corner case: eg. { 75, 75 }
        if( array[pos_max] <= array[i] ) pos_max = i ;

       sum += array[i] ;
    }

    sum -= array[pos_min] + array[pos_max] ;

    array[pos_min] = 0 ;
    array[pos_max] = 0 ;

    return sum / sz ;
}

int main() {

    const int N = 10 ;
    int input[N] = { 85, 38, 77, 20, 28, 6, 70, 88, 12, 27 };
    std::cout << zero_minmax_and_average( input, N ) << '\n' ; // 35.7
}

http://coliru.stacked-crooked.com/a/6b1d7974a601b107
Last edited on
True, but corner case N==1:
1
2
3
4
5
int main() {
    const int N = 1 ;
    int input[N] = { 42 };
    std::cout << zero_minmax_and_average( input, N ) << '\n' ; // -42
}

That is "easy" to fix though:
1
2
3
4
5
if( array == nullptr || sz < 1 ) {
  return double(NAN) ;
} else if ( sz == 1 ) {
  // do/return something
}
Yes, thanks. Correcting it now.
Oops, all I had to do was change the array element to be null and it works as needed.
1
2
3
4
5
6
7
8
9
for (int a = 0; a < sizeofArray; a++) {
	//Replacing largest and smallest value
	if (smallest == theArray[a]) {
		theArray[a] = NULL;
	}
	if (largest == theArray[a]) {
		theArray[a] = NULL;
	}
}
Topic archived. No new replies allowed.