编辑:明确一点,结果不必存在于数组中。 也就是说,对于输入数组 [3, 6, 7],期望结果是 5。此外,我想我们需要指定一个特定的舍入方向,因此如果您距离两个数字同样接近,则向下舍入。
编辑:这不是作业。 我已经五年没有作业了。 而且这是我第一次在 stackoverflow 上,所以请友好一些!
编辑:显然的方法是将总和除以数量,但可能会溢出,因此我正在尝试思考一种安全处理溢出的方法,适用于大型数组和大型 int。 我认为正确处理溢出(而不作弊并使用不同类型)是这个问题中最难的部分。
// The length of someListOfNumbers doesn't need to be known in advance.
int mean(SomeType someListOfNumbers) {
double mean = 0, count = 0;
foreach(element; someListOfNumbers) {
count++;
mean += (element - mean) / count;
}
if(count == 0) {
throw new UserIsAnIdiotException(
"Problem exists between keyboard and chair.");
}
return cast(int) floor(mean);
}
那就先计算平均值,然后四舍五入到整数?round(mean(thearray))
大多数语言都有可以指定舍入方法的工具。
编辑:结果发现这个问题实际上是关于避免溢出,而不是关于舍入。让我明确一点,我同意评论中说的那些话,这在实践中不是需要担心的事情,因为它很少发生,当它发生时,你总是可以使用更大的数据类型来解决。
我看到其他几个人给出的答案基本上是将数组中的每个数字除以数组的计数,然后将它们相加。这也是一个不错的方法。但只是为了好玩,这里是一个替代方案(C风格的伪代码):
int sum_offset = 0;
for (int i = 1; i < length(array); i++)
sum_offset += array[i] - array[i-1];
// round by your method of choice
int mean_offset = round((float)sum_offset / length(array));
int mean = mean_offset + array[0];
或者用另一种方式实现相同的功能:
int min = INT_MAX, max = INT_MIN;
for (int i = 0; i < length(array); i++) {
if (array[i] < min) min = array[i];
if (array[i] > max) max = array[i];
}
int sum_offset = max - min;
// round by your method of choice
int mean_offset = round((float)sum_offset / length(array));
int mean = mean_offset + min;
当然,您需要确保sum_offset
不会溢出,如果数组中最大元素和最小元素之间的差大于INT_MAX,则可能发生溢出。在这种情况下,请将最后四行替换为以下内容:
// round by your method of choice
int mean_offset = round((float)max / length(array) - (float)min / length(array));
int mean = mean_offset + min;
趣闻:这种方法(或类似的方法)也能很好地计算元素聚集在一起的数组的平均值。
通过将数字相加并除以它们的数量,四舍五入计算总和:
mean = (int)((sum + length/2) / length;
int mean = 0, remainder = 0
foreach n in number
mean += n / length
remainder += n % length
if remainder > length
mean += 1
remainder -= length
if remainder > length/2
mean += 1
print "mean is: " mean
保证不会溢出:
length ← length of list
average ← 0
for each result in the list do:
average ← average + ( result / length )
end for
如果您使用整数,由于截断,这会导致准确性方面的重大问题(六个4的平均值为0)
欢迎。fish,希望您在这里过得愉快。
以下伪代码展示了如何在总和适合整数类型的情况下进行操作,并且 round 四舍五入到最近的整数。
在您的样本中,数字相加总和为16,除以3得到5 1/3,四舍五入为5。
sum = 0
for i = 1 to array.size
sum = sum + array[i]
sum = sum / array.size
sum = round (sum)
这个伪代码可以找到平均值并解决溢出问题:
double avg = 0
int count = 0
for x in array:
count += 1
avg = avg * (count - 1) / count // readjust old average
avg += x / count // add in new number
之后,您可以应用您的四舍五入代码。如果您的语言没有简单的四舍五入方法,那么类似这样的代码将起作用(当超过0.5时向上取整):
int temp = avg - int(avg) // finds decimal portion
if temp <= 0.5
avg = int(avg) // round down
else
avg = int(avg) + 1 // round up
ARM汇编。未测试。永远不会溢出。(我希望如此。)
可能可以稍微优化一下。(也许使用FP / LR?)= S 可能在这里使用THUMB效果更好。
.arm
; r0 = pointer to array of integers
; r1 = number of integers in array
; returns mean in r0
mean:
stmfd sp!, {r4,r5}
mov r5, r1
mov r2, 0 ; sum_lo
mov r3, 0 ; sum_hi
cmp r1, 0 ; Check for empty array
bz .end
.loop:
ldr r4, [r0], #4
add r2, r2, r4
adc r3, r3, #0 ; Handle overflow
sub r1, r1, #1 ; Next
bnz .loop
.end:
div r0, r2, r3, r5 ; Your own 64-bit/32-bit divide: r0 = (r3r2) / r5
bx lr
获取平均值的伪代码:
double mean = 0
int count = 0
foreach int number in numbers
count++
mean += number - mean / count
round(mean) // rounds up
floor(mean + 0.5) // rounds up
ceil(mean - 0.5) // rounds down
舍入通常涉及添加0.5,然后截断(向下取整),这就是为什么3.5四舍五入到4。如果您想让3.5向下舍入到3,请自己编写舍入代码,但要反过来:减去0.5,然后找到上限。
编辑:更新要求(无溢出)