C#中判断数值所属区间并获取对应折扣的高效实现方案
区间匹配折扣高效实现方案
因为你的区间本身是互斥无重叠的连续区间,完全可以用二分查找替代线性遍历,将查询的时间复杂度从原方案的O(n) 降到 O(log n),区间数量越多性能提升越明显。
实现逻辑
- 先做一次全局预处理:将所有
IndividualFee按MinValue升序排序,把MaxValue为null的最高区间放在列表末尾 - 提取所有区间的
MinValue生成独立的有序数组,作为二分查找的索引 - 查询时对有序
MinValue数组做二分查找,找到最后一个小于等于目标值的MinValue对应的区间,就是匹配结果
C# 实现代码
预处理步骤只需执行一次(比如FeeDTO初始化、区间列表更新时执行),无需每次查询都重复排序:
public class FeeDiscountCalculator { private readonly List<IndividualFee> _sortedFeeList; private readonly int[] _sortedMinValues; public FeeDiscountCalculator(FeeDTO feeDto) { // 排序规则:按MinValue升序,上限为无穷大(MaxValue为null)的区间放在最后 _sortedFeeList = feeDto.Fees .OrderBy(fee => fee.MaxValue.HasValue ? fee.MinValue : int.MaxValue) .ToList(); // 提取Min值数组用于二分查找 _sortedMinValues = _sortedFeeList.Select(fee => fee.MinValue).ToArray(); } public string GetMatchedDiscount(int targetValue) { // 二分查找目标值在Min数组中的位置 var searchIndex = Array.BinarySearch(_sortedMinValues, targetValue); // 未命中时取补码换算出最后一个小于目标值的Min值索引 if (searchIndex < 0) { searchIndex = ~searchIndex - 1; } // 索引合法直接返回对应折扣 if (searchIndex >= 0 && searchIndex < _sortedFeeList.Count) { return _sortedFeeList[searchIndex].DiscountValue; } // 无匹配时可按业务需求返回默认值 return string.Empty; } }
适用场景说明
- 如果你的区间数量很少(少于10个),原有的倒序线性遍历方案性能已经足够,不需要额外改造
- 如果区间数量超过20个,或者后续有区间数量增长的预期,更推荐使用上述二分查找方案
内容的提问来源于stack exchange,提问作者SP1
相关产品推荐
相关产品推荐

