我有一个配置了折扣值和适用量范围的报价。
它可能适用于一个产品的多个报价,所以我正在寻找算法来合并各种报价之间的重叠量范围并显示适用的最终折扣。下面的代码片段将有助于可视化询问:
class VolumeTierRange
{
public int Min { get; set; }
public int Max { get; set; }
public int Discount { get; set; }
}
/* Offer1Range */
List<VolumeTierRange> Offer1Ranges = new List<VolumeTierRange>{
new VolumeTierRange {Min=1, Max=20, Discount=2 },
new VolumeTierRange {Min=21, Max=49 , Discount=10 },
new VolumeTierRange {Min=50, Max=100 , Discount=5 },
new VolumeTierRange {Min=101, Max=1000, Discount=15}
};
/* Offer2Range */
List<VolumeTierRange> dicountBRanges = new List<VolumeTierRange>{
new VolumeTierRange {Min = 1, Max=50, Discount=6},
new VolumeTierRange {Min=51, Max=1000, Discount=10 }
};
综合结果如下:
List<VolumeTierRange> effectiveDiscount = new List<VolumeTierRange>{
new VolumeTierRange {Min=1, Max=20, Discount=8 },
new VolumeTierRange {Min=21, Max=49, Discount=16},
new VolumeTierRange {Min=50, Max=50, Discount=11},
new VolumeTierRange {Min=51, Max=100, Discount=15},
new VolumeTierRange {Min=101,Max=1000,Discount=25}
};
我确实有一些方法可以达到预期的结果,但这些方法似乎都不是很直观。
附加信息:第一项的最小值和所有报价的最大值是固定的(如本例中的 1 和 1000)。定义体积范围时也不能有不连续性。
最佳答案
好吧,您要做的第一件事是找出 Offer1Ranges
中的哪些值与 dicountBRanges
中的值重叠。
当第一个项目的最小值小于(或等于*)第二个项目的最大值,而第二个项目的最小值小于(或等于*)第一个项目的最大值时,项目重叠元素。有关详细信息,请参阅 overlap标签 info .
根据重叠项目加入列表后,选择两个最小值中的最大值、两个最大值中的最小值以及每个项目的折扣值之和就足够简单了:
var query = from o in Offer1Ranges
from d in dicountBRanges
where o.Min <= d.Max
&& o.Max >= d.Min
select new VolumeTierRange()
{
Min = (o.Min > d.Min) ? o.Min : d.Min,
Max = (o.Max < d.Max) ? o.Max : d.Max,
Discount = o.Discount + d.Discount
};
You can see a live demo or rextester.
*在您的情况下,您认为项目重叠,即使它在一个点上(第一个最小值等于第二个最大值,反之亦然)。这不是一般情况。
请注意:此解决方案仅在两个列表以相同数字开始和结束且没有间隙时才有效,如问题中所述:
"Additional Info: Min value of first item and Max value of all offers is fixed (like 1 and 1000 in this example). Also there cannot be discontinuity while defining volume range."
关于c# - 合并重叠范围的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49230148/