gpt4 book ai didi

linq - 在集合中找到要四舍五入的最大数字,然后将其四舍五入

转载 作者:行者123 更新时间:2023-12-04 17:41:08 27 4
gpt4 key购买 nike

正如标题所描述的,我有一组对象——称它们为分配——其中包含一个描述和一个数字。集合中的所有数字加起来为 100%,但为了显示目的,我有时会四舍五入到整数百分比。在某些边缘情况下,四舍五入的数字最终得到 99%。

例子:

Description  | Actual | Rounded
===============================
Allocation A | 65.23% | 65%
Allocation B | 25.40% | 25%
Allocation C | 7.95% | 8%
Allocation D | 1.42% | 1%
===============================
Total | 100% | 99% (Bad!)

所要求的解决方案是不完美但可行的解决方案是找到最高的四舍五入,然后将其四舍五入。在上面的示例中,四舍五入后 1.42% 将变为 2%。 编辑:“最高四舍五入”是指四舍五入最远的那个。因此 1.42% 被四舍五入 0.42 而 65.23 只被四舍五入 0.23

所以现在的代码,我有一个类
public class Allocation
{
public string Description {get;set;}
public doubel Percentage {get;set;}
}

这些都保存在 IEnumerable<Allocation> 中.因此,可能会使用 LINQ,我如何确定要四舍五入的那个。或者更具体地说,我如何生成一个新的 IEnumerable<Allocation>数字四舍五入。

如果有人对始终使四舍五入的百分比始终等于 100% 有任何其他建议,那就更好了!

最佳答案

正如 ho1 所指出的,将 1 添加到特定行的解决方案并不能解决真正的问题。

考虑以下场景:

3 items evenly divided, 100/3 = 33 ; 33 * 3 = 99 ; Error = -1
7 items evenly divided, 100/7 = 14 ; 14 * 7 = 98 ; Error = -2
66 items evenly divided, 100/66 = 2 ; 2 * 66 = 132 ; Error = 32

这里有一些未经测试的代码,它们可能会让你接近你需要去的地方。这里可能有一个符号错误,所以要小心。
public class AllocationRoundingWrapper
{
public Allocation Original {get;set;}
public double Rounded {get;set;}
public double IntroducedError()
{
return Rounded - Original.Percentage;
}
}

//project the Allocations into Wrappers for rounding efforts.

List<Allocation> source = GetAllocations();

List<AllocationRoundingWrapper> roundingWrappers = source
.Select(a => new AllocationRoundingWrapper()
{
Original = a,
Rounded = Math.Round(a.Percentage)
}).ToList();

int error = (int) roundingWrappers.Sum(x => x.IntroducedError());

//distribute the rounding errors across the
// items with the absolute largest error.

List<RoundingWrapper> orderedItems = error > 0 ?
roundingWrappers.OrderByDescending(x => x.IntroducedError()).ToList() :
roundingWrappers.OrderBy(x => x.IntroducedError()).ToList();

IEnumerator<RoundingWrapper> enumerator = orderedItems.GetEnumerator();

while(error > 0)
{
enumerator.MoveNext();
enumerator.Current.Rounded += 1.0;
error -= 1;
}
while(error < 0)
{
enumerator.MoveNext();
enumerator.Current.Rounded -= 1.0;
error += 1;
}

//project back into Allocations for the result
List<Allocation> result = roundingWrappers
.Select(x => new Allocation()
{
Description = x.Original.Description,
Percentage = x.Rounded
}).ToList();

注意:按引入的错误排序可能会导致平局。考虑 3 个项目的情况,只有一个项目会获得 +1……您可能希望该项目始终被选中。如果多次运行预期结果一致,则应打破平局。

关于linq - 在集合中找到要四舍五入的最大数字,然后将其四舍五入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3611015/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com