C#实现移除数据行后剩余金额按比例分配保持总和恒定
C#实现移除行后按比例调整金额保持总和恒定的方案
需求说明
给定原始数据(总和固定为3000):
| Name | Amount |
|---|---|
| Val 1 | 500 |
| Val 2 | 600 |
| Val 3 | 350 |
| Val 4 | 500 |
| Val 5 | 450 |
| Val 6 | 600 |
当移除任意一行或多行数据后,剩余行的Amount需按原始占比重新计算,确保调整后的总和仍为3000。
实现步骤与代码
1. 定义数据实体类
首先定义存储数据的实体,用于承载每一行的名称和金额:
public class Item { public string Name { get; set; } public decimal Amount { get; set; } }
2. 核心调整逻辑
实现核心方法,完成移除指定项、计算比例、调整金额的功能:
public static List<Item> AdjustAmountsAfterRemoval(List<Item> originalItems, List<string> itemsToRemove) { const decimal TargetTotal = 3000m; // 过滤掉需要移除的项 var remainingItems = originalItems .Where(item => !itemsToRemove.Contains(item.Name)) .ToList(); // 计算剩余项的原始总金额 decimal remainingOriginalTotal = remainingItems.Sum(item => item.Amount); // 无剩余项时直接返回空列表(可根据业务需求修改) if (remainingOriginalTotal == 0) return remainingItems; // 按原始占比调整金额 foreach (var item in remainingItems) { decimal ratio = item.Amount / remainingOriginalTotal; // 保留两位小数,可根据业务需求调整精度 item.Amount = Math.Round(TargetTotal * ratio, 2); } // 修正四舍五入导致的总和偏差(比如总和可能差0.01或0.02) decimal adjustedTotal = remainingItems.Sum(item => item.Amount); decimal difference = TargetTotal - adjustedTotal; if (difference != 0) { // 将差值加到金额最大的项上,也可选择加到第一个项或其他规则 var targetItem = remainingItems.OrderByDescending(i => i.Amount).First(); targetItem.Amount += difference; } return remainingItems; }
3. 示例调用
以下是调用示例,演示移除Val 3和Val 5后的调整效果:
// 初始化原始数据 var originalItems = new List<Item> { new Item { Name = "Val 1", Amount = 500 }, new Item { Name = "Val 2", Amount = 600 }, new Item { Name = "Val 3", Amount = 350 }, new Item { Name = "Val 4", Amount = 500 }, new Item { Name = "Val 5", Amount = 450 }, new Item { Name = "Val 6", Amount = 600 } }; // 指定要移除的项名称 var itemsToRemove = new List<string> { "Val 3", "Val 5" }; var adjustedItems = AdjustAmountsAfterRemoval(originalItems, itemsToRemove); // 输出调整后的结果 foreach (var item in adjustedItems) { Console.WriteLine($"名称:{item.Name},调整后金额:{item.Amount}"); }
关键注意事项
- 精度处理:使用
decimal类型而非double,避免浮点数精度丢失;Math.Round的保留位数可根据业务需求调整。 - 偏差修正:四舍五入后总和可能与目标值有微小偏差,代码中通过调整金额最大项的方式修正,也可自定义其他修正规则。
- 边界情况:当所有项都被移除时,直接返回空列表,可根据业务场景添加提示或异常处理。
内容的提问来源于stack exchange,提问作者Abhigyan Srivastava
相关产品推荐
相关产品推荐

