c# - 合并重叠范围的算法

标签 c# algorithm linq

我有一个配置了折扣值和适用量范围的报价。

它可能适用于一个产品的多个报价,所以我正在寻找算法来合并各种报价之间的重叠量范围并显示适用的最终折扣。下面的代码片段将有助于可视化询问:

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 中的值重叠。
当第一个项目的最小值小于(或等于*)第二个项目的最大值,而第二个项目的最小值小于(或等于*)第一个项目的最大值时,项目重叠元素。有关详细信息,请参阅 标签 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/

相关文章:

c# - 是否应该将依赖项注入(inject)比需要的多很多 "levels"?

C# 4.0 : dynamic 'this' pointer

c# - 自定义(派生)List<T>

c# - 使用额外变量的 Linq 多重连接条件

c# - 如何使用 Linq 读取 XML

c# - 在 WCF 中序列化委托(delegate)

c# - 列出依赖解析器 DefaultConstructorFinder 的所有缺失的 Autofac 注册

algorithm - 通过后备数组中的索引交换双向链表中的项目

c++ - C++数据结构的时间范围查询

c++ - 将 STL 算法与 Qt 容器结合使用