var pairs = from f in list
from s in list
where (f.EndTime < s.StartTime) && (f.StartTime < s.EndTime) && (f != s)
select new {First = f, Second = s };
public class ScheduleList : List<Schedule>
{
private BitArray ba = new BitArray(1440);
// Define own Add method to Add a Schedule to the list
// Or override the predefined one....
public Schedule Add(int sh, int sm, int eh, int em)
{
Schedule s = new Schedule();
s.StartTime = new DateTime(1, 1, 1, sh, sm, 0);
s.EndTime = new DateTime(1, 1, 1, eh, em, 0);
// Of course, having full control on the Add phase, you
// could easily enforce your policy at this point.
// You could not accept a new schedule if the time slot is busy
// but we could ignore it at this point
this.Add(s);
return s;
}
public bool IsTimeSlotBusy(Schedule s)
{
int sidx = Convert.ToInt32(TimeSpan.FromMinutes((s.StartTime.Hour * 60) + s.StartTime.Minute).TotalMinutes);
int eidx = Convert.ToInt32(TimeSpan.FromMinutes((s.EndTime.Hour * 60) + s.EndTime.Minute).TotalMinutes);
for (int x = sidx; x <= eidx; x++)
{
if (ba.Get(x)) return true;
ba.Set(x, true);
}
return false;
}
}
4条答案
按热度按时间vhmi4jdf1#
如果您只关心是否存在重叠,而不关心哪些计划重叠,那么您应该能够在O(n log n)。关键是按
StartTime
和EndTime
对计划进行排序然后你可以枚举结果并将每个调度的StartTime
与前一个调度的EndTime
进行比较。如果StartTime
早于EndTime
,那么您就有了重叠的调度。但是,如果没有第三方的帮助,我不认为这可以在一个查询中完成。我自己就是Ix-Main
的爱好者。下面的解决方案使用了Ix-Main
中的Buffer
函数:如果您不想使用第三方库,则可以使用以下库执行相同的操作:
qlvxas9a2#
假设性能不是问题(否则考虑an algorithm for overlaps):
基本上,我们在检查所有可能的配对是否有重叠。
或者,如果不使用查询语法:
xpszyzbs3#
一种不同的方法,我不确定整个事情的性能,但想法是在BitArray中展平由您的时间表定义的范围,如果特定的分钟已经被前一个时间表使用,则发出信号。
从技术上讲,它也不是“一行”的答案,尽管从调用代码的Angular 来看,它只是一行
因此假设已经定义了类ScheduleList
现在你可以这样写
等待这里的数学家告诉我为什么这是最糟糕的。(不是讽刺,我真的希望知道这是不是从数学的Angular 来看是不好的)
z4iuyo4d4#
对于任何需要此功能的人,它不是问题所要求的一行程序,而是解决检查重叠DateTime元素与Start和End日期问题的简单方法
1.使用
OrderBy Linq
运算符对列表进行排序。1.不允许开始
DateTime
大于结束DateTime
。1.跟踪以前每次会议的结束时间,查看它是否与计划的
DateTime
的下一次开始时间重叠。