yuwen

机票订单会根据情况被拆为多单,每单在不同时间范围内对应不同的退票费。

如:订单拆为两单,分别在不同时间段退票费如下

 

求所有时间段的退票费。

 

算法如下:

首先定义一个退票费的类如下

    /// <summary>
    /// 时间段对应退票费列表
    /// </summary>
    class RefundFeeRange
    {
        public RefundFeeRange(int st, int en, List<int> fl)
        {
            Start = st; End = en; Fees = fl;
        }
        //起始时间点
        public int Start { get; set; }
        //结束时间点
        public int End { get; set; }
        //时间段内退票费
        public List<int> Fees { get; set; }
    }

 

 

        //判断两个时间段是否有交叉
        static bool IsTimeConflict(RefundFeeRange a, RefundFeeRange b)
        {
            return a.Start >= b.End || a.End <= b.Start;
        }

 

       /// <summary>
        /// 由多个可能冲突的时间段对应退票费,算出不冲突的时间段的退票费集合
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        static List<RefundFeeRange> RefundFeeCaculate(List<RefundFeeRange> param)
        {
            //时间段对应退票费集合
            var temps = new List<RefundFeeRange>();
            //获得所有不重复的时间点集合
            var timePointList = new List<int>();
            param.ForEach(x =>
            {
                timePointList.Add(x.Start);
                timePointList.Add(x.End);
            });
            timePointList = timePointList.OrderBy(x => x).Distinct().ToList();
            //获得所有不冲突的时间段集合
            for (int i = 0; i < timePointList.Count - 1; i++)
            {
                temps.Add(new RefundFeeRange(timePointList[i], timePointList[i + 1], new List<int>()));
            }
            //获得每个时间段内对应的不同航班的退票费
            temps.ForEach(x =>
            {
                param.ForEach(y =>
                {
                    if (!IsTimeConflict(x, y))
                    {
                        x.Fees.AddRange(y.Fees);
                    }
                });
            });
            return temps;
        }

 

以前面的数据为例计算

        static void Main(string[] args)
        {
            var li = new List<RefundFeeRange>() {
                new RefundFeeRange(0,5,new List<int>(){100}),
                new RefundFeeRange(5,8,new List<int>(){200}),
                new RefundFeeRange(8,10,new List<int>(){300}),
                new RefundFeeRange(0,3,new List<int>(){150}),
                new RefundFeeRange(3,9,new List<int>(){220}),
                new RefundFeeRange(9,10,new List<int>(){330})
            };
            var temps = RefundFeeCaculate(li);
            temps.ForEach(x =>
            {
                Console.WriteLine(String.Format("{0}------{1}--------{2} : {3}", x.Start, x.End, x.Fees.Sum(), string.Join(",", x.Fees)));
            });
            Console.ReadLine();
        }

输出结果如下

 

对比实际

 

分类:

技术点:

相关文章: