You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#实现移除数据行后剩余金额按比例分配保持总和恒定

C#实现移除行后按比例调整金额保持总和恒定的方案

需求说明

给定原始数据(总和固定为3000):

NameAmount
Val 1500
Val 2600
Val 3350
Val 4500
Val 5450
Val 6600

当移除任意一行或多行数据后,剩余行的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 21:27:34