简体   繁体   English

查找给定数组的平均值

[英]Finding average of a given array

I am trying to answer the following:我正在尝试回答以下问题:

Implement a function that is given an array of integers and the number of items.实现一个给定整数数组和项目数的函数。 It should return the rounded (to the nearest integer) average of the numbers.它应该返回数字的四舍五入(到最接近的整数)平均值。

This is my code:这是我的代码:

#include <stddef.h>
int CalculateAverage (const int array[], size_t size)
{
    
    int i;
    long total;
    float convert;
    int temp = 0;
    int average;
    if (size == 0)
    {
        return 0;
    }
    for (i=0; i<size; i++)
    {
        temp = total;
        total = temp + array[i];
    }
    
    convert = total;
    convert = convert / size;
    average = (convert > 0) ? convert + 0.5 : convert - 0.5;
    
    return average;
}

I can't use any functions.我无法使用任何功能。 When I run the test on our class tutorial app I get (every time with different inputs):当我在我们的课程教程应用程序上运行测试时,我得到(每次都有不同的输入):

Testing Report:
Running test: CalculateAverage(size=11)  --  Passed
Running test: CalculateAverage(size=13)  --  Failed

Done

I am not sure where is my mistake.我不确定我的错误在哪里。 I think it is related to negative/positive inputs.我认为这与负/正输入有关。 any suggestions?有什么建议么?

Main issue: Uninitialized object主要问题:未初始化的对象

Below is bad as total is read, but not yet initialized nor assigned.下面是坏的,因为total已读取,但尚未初始化或分配。 @abelenky @abelenky

long total;
 ...
    temp = total;

long not that wide long没那么宽

Good that OP is trying to accumulate the sum in a wider type, yet long is not certainly twice as wide as int *1 .好在 OP 试图以更广泛的类型累积总和,但long的宽度肯定不会是int *1的两倍。 Consider long long or intmax_t .考虑long longintmax_t Even those are not certain to be wider, yet commonly are wider.即使那些不一定更宽,但通常更宽。

Wrong rounding四舍五入错误

convert + 0.5 not needed as prior convert / size already rounded. convert + 0.5不需要,因为之前的convert / size已经四舍五入了。 Floating point math not needed.不需要浮点数学。 Conversion to float risks losing precision.转换为float有失去精度的风险。 Use of double math with float object is curious.float对象使用double数学很奇怪。

Wrong type类型错误

Iterator i should match type of size .迭代器i应该匹配size的类型。

Good use of const and size==0 detection好好利用constsize==0检测


Proposed fix建议修复

#include <inttypes.h>
#include <stddef.h>

int CalculateAverage (const int array[], size_t size) {
  if (size == 0) {
    return 0;
  }
  intmax_t sum = 0;
  for (size_t i = 0; i<size; i++) {
    sum += array[i];
  }

  // Form a rounded average by subtracting/adding half the size before the division.
  // For handling ties and round to even obliges a little more code.
  sum = (sum < 0) ? sum - size/2 : sum + size/2;
  return (int) (sum / size);
}

*1 The width needed is the width of int plus the width of size_t . *1所需的宽度是int的宽度加上size_t的宽度。 To truly handle very extreme averaging, takes additional code.要真正处理非常极端的平均,需要额外的代码。

To add to the comments you could make it more understandable by accumulating the results of division and reminders of division in 2 varaibles like this:要添加到评论中,您可以通过在 2 个变量中累积除法结果和除法提醒来使其更易于理解,如下所示:

int CalculateAverage(const int array[], size_t size) {
    if (size == 0) return 0;
    int sum_of_divided = 0, sum_of_remainders = 0;
    for (int i = 0; i < size; i++) {
        sum_of_divided += array[i] / size;
        sum_of_remainders += array[i] % size;
    }
    return sum_of_divided + sum_of_remainders / size;
}

This doesn't require floats and is thus not susceptible to floating point precision errors.这不需要浮点数,因此不易受浮点精度错误的影响。

Problem solved based on this comment from @abelenky: long total = 0 .根据@abelenky 的评论解决了问题: long total = 0

 //Working example #include <stdio.h> #include <stddef.h> #include <math.h> void main() { float CalculateAverage (int array[], int arr_size) { int total=0; float average=0; if (arr_size == 0) { return 0; } for (int i=0; i<arr_size; i++) { total += array[i]; } printf("Size of array = %d", arr_size); printf("\nSum of array = %d", total); average = (float) total / arr_size; printf("\nActual average = %f", average); return average; } int numArray[] = {7, 8, 9, 11, 13}; int arr_size = sizeof(numArray)/sizeof(numArray[0]); //You can manually pass the array size if you don't want to use any built-in function float avg = CalculateAverage(numArray, arr_size); if(avg>0) { float tempNum = avg*10; float reminder = fmodf(tempNum, 10); if(reminder >= 5) { avg++; } printf("\nRounded off average = %d", (int)avg); } else{ printf("Average = %lf", avg); } }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM