机票订单会根据情况被拆为多单,每单在不同时间范围内对应不同的退票费。
如:订单拆为两单,分别在不同时间段退票费如下
求所有时间段的退票费。
算法如下:
首先定义一个退票费的类如下
/// <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(); }
输出结果如下
对比实际