3 回答
TA贡献1786条经验 获得超12个赞
由于这里的答案似乎都无法正确解决,因此这是我使用underscorejs的半混淆版本:
function foo(l, target) {
var off = target - _.reduce(l, function(acc, x) { return acc + Math.round(x) }, 0);
return _.chain(l).
sortBy(function(x) { return Math.round(x) - x }).
map(function(x, i) { return Math.round(x) + (off > i) - (i >= (l.length + off)) }).
value();
}
foo([13.626332, 47.989636, 9.596008, 28.788024], 100) // => [48, 29, 14, 9]
foo([16.666, 16.666, 16.666, 16.666, 16.666, 16.666], 100) // => [17, 17, 17, 17, 16, 16]
foo([33.333, 33.333, 33.333], 100) // => [34, 33, 33]
foo([33.3, 33.3, 33.3, 0.1], 100) // => [34, 33, 33, 0]
TA贡献1802条经验 获得超10个赞
只要您不担心依赖原始十进制数据,有许多方法可以做到这一点。
第一种,也许是最受欢迎的方法是最大剩余法
基本上是:
四舍五入
求和与100之差
通过以小数部分的降序向项目加1来分配差异
在您的情况下,它将如下所示:
13.626332%
47.989636%
9.596008%
28.788024%
如果取整数部分,则得到
13
47
9
28
总计为97,而您想再添加三个。现在,您看一下小数部分,它们是
.626332%
.989636%
.596008%
.788024%
并选择最大的,直到总数达到100。这样您将获得:
14
48
9
29
另外,您可以选择显示小数点后一位而不是整数。因此,数字将是48.3和23.9等。这将使方差从100下降很多。
TA贡献1820条经验 获得超10个赞
做到这一点的“最佳”方法可能是保持您所在位置的连续(非整体)统计并舍入该值,然后将其与历史记录一起使用以确定应该使用什么值。例如,使用您提供的值:
Value CumulValue CumulRounded PrevBaseline Need
--------- ---------- ------------ ------------ ----
0
13.626332 13.626332 14 0 14 ( 14 - 0)
47.989636 61.615968 62 14 48 ( 62 - 14)
9.596008 71.211976 71 62 9 ( 71 - 62)
28.788024 100.000000 100 71 29 (100 - 71)
---
100
在每个阶段,您都不会对数字本身进行四舍五入。取而代之的是,您对累计值进行四舍五入,并计算出从上一个基线达到该值的最佳整数-该基线是前一行的累积值(四舍五入)。
之所以可行,是因为您不会在每个阶段都丢失信息,而是更智能地使用信息。“正确”的四舍五入值在最后一列中,您可以看到它们的总和为100。
添加回答
举报