2013-04-27 80 views
0

我正在制定一个时间表的一段代码。我使用的大学模块和相关于这些模块事件的系统,即比较重叠的日期 - 不避免

模块CSC3039 事件1 - 讲座 事件2 - 讲座 EVENT3 - Practial等

我需要检查每一个事件的时间在模块相互对抗并比较冲突。冲突不需要纠正,只是突出显示。我将使用的表格是Events,其中包含Event_ID (PK), Module_code (FK), Start_Date_Time, End_Date_Time加上其他无关紧要的字段。我已经想通了,我需要实现一个For Each声明,最终导致if语句如:

如果(startTime1 < = endTime2或endTime1> = startTime2)CLASH

我的问题是试图找出这里的实际循环。我不知道该写什么来宣布我的开始时间和结束时间。我认为这是一个事件1并获取其开始和结束,然后检查事件2,3或4是否符合上述if语句的情况。我试图得到这个,但可以真正使用一些指导。

编辑...基于下面的建议我已经实现了下面的代码:

'return all relevant tables from the Modules database, based on the module code entered by the user. 
    Dim eventTime = (From mods In db.Modules 
        Join evnt In db.Events On mods.Module_code Equals evnt.Module_code 
        Join rm In db.Rooms On rm.Room_ID Equals evnt.Room_ID 
        Join build In db.Buildings On build.Building_code Equals rm.Building_code 
        Where ((mods.Module_code = initialModCode) And (evnt.Room_ID = rm.Room_ID)) 
        Select evnt.Event_ID, evnt.Module_code, evnt.Event_type, evnt.Start_Date_Time, evnt.End_Date_Time, build.Building_code, rm.Room_Number) 


    'use the gridview to display the result returned by the above query 
    gdvEventsTable.DataSource = eventTime 
    gdvEventsTable.DataBind() 

    Dim listClashes As New List(Of Array) 

    For i As Integer = 0 To eventTime.Count - 1 
     For j As Integer = i + 1 To eventTime.Count - 1 
      If (eventTime.ToList(i).Start_Date_Time < eventTime.ToList(j).End_Date_Time) And (eventTime.ToList(i).End_Date_Time > eventTime.ToList(j).Start_Date_Time) Then 
       MsgBox("Clash", MsgBoxStyle.MsgBoxSetForeground, "") 
       listClashes.Add(eventTime) 
      Else 
       MsgBox("No Clash", MsgBoxStyle.MsgBoxSetForeground, "") 
      End If 
     Next 
    Next 

当试图将事件添加到我的数组列表,我注意到,在调试,没有事件发送到名单。

+0

好吧,现在这是越来越linq具体,我从来没有使用linq,所以我不知道这个东西。您需要以某种方式获取eventTime的第i个元素。在调试时将鼠标放在它上面,以查看eventTime是什么类型的对象,然后将它放到Google或其他位置。你也可以从gridview中获得所有的信息,这可能会更容易。 – 2013-04-28 20:09:59

+0

你应该使用包容/排他的范围,而不是完全包含的范围。看到[我的回答](http://stackoverflow.com/a/16282246/634824)刚刚发布的类似问题。 – 2013-04-29 15:31:05

回答

1

如果你想这是一个数组或某种收集的事件的所有成对比较,你可以用这样一个循环:

Dim ModuleEventArray() As ModuleEvent 
    '... 
    For i As Integer = 0 To ModuleEventArray.Length - 1 
     For j As Integer = i + 1 To ModuleEventArray.Length - 1 
      'test if ModuleEventArray(i) overlaps with ModuleEventArray(j) 
     Next 
    Next 

ModuleEvent这里将是另一个类或结构有字段startTime和endTime。测试

if (startTime1 <= endTime2 or endTime1 >= startTime2) 

是不够的测试重叠,但也许你可以计算出正确的测试自己:)


编辑: 因为我看你使用某种形式的集合,而不是数组,你需要的代码应该是这样的:

For i As Integer = 0 To eventTime.Count - 1 
    For j As Integer = i + 1 To eventTime.Count - 1 
     If (eventTime.Item(i).Start_Date_Time < eventTime.Item(j).End_Date_Time) And (eventTime.Item(i).End_Date_Time > eventTime.Item(j).Start_Date_Time) Then 
      MsgBox("Clash") 
     Else 
      MsgBox("No Clash") 
     End If 
    Next 
Next 
+0

感谢@SauliusŠimčikas的简化。我很感激。该代码没有工作,因为它不喜欢'eventTime.Item'行。我改变了这个'eventTime.ToList'似乎已经工作,但我无法发送冲突事件到我的数组列表。我已更新我的问题以显示我现在使用的代码。请给我你的想法。提前致谢。 – Gavin 2013-04-28 18:09:27

0

之前,你写你的代码,你需要首先决定你的算法将是。例如,如果您使用您所设想的朴素方法,则代码确实很简单(基本上是2个嵌套循环),但是如果O(n²)是复杂的。

根据您拥有的数据量,数据库中是否有数据,您预期冲突的可能性,您是否始终在开始时拥有完整事件列表,或者您需要逐步查找冲突等。不同的解决方案可能是首选。其中一个考虑因素是您是否需要将列表划分为非冲突事件集或者只是产生一个是/否的答案(每个事件一个),说明是否存在冲突。

您可能会考虑做一些不同的事情,比如在开始比较之前按开始时间排序列表。这将允许你只走一次列表。

+0

感谢您的输入@Celada。由于我是一个没有经验的编码员,因此我的头脑有点过分了。数据位于数据库中,不会包含大量数据。冲突可以说是频繁的。我不知道你的意思是O(n2) – Gavin 2013-04-27 23:57:13

0

我的比较来自数据库。在下面的代码之前,我有一个查询,根据Module_Code的用户输入,从我的Events表中返回所有记录。这段代码将通过msgbox显示冲突。我会改变它来填充一个列表。这不是最漂亮的,可能会导致很多重复,但它实现了我的主要目标。

For Each evnt In eventTime 


     Dim startTime1 = evnt.Start_Date_Time 

     Dim endTime1 = evnt.End_Date_Time 

     For Each evat In eventTime 
      Dim startTime2 = evat.Start_Date_Time 


      Dim endTime2 = evat.End_Date_Time 



      If (startTime1 < endTime2) And (endTime1 > startTime2) Then 
       MsgBox("Clash") 
      Else 
       MsgBox("No Clash") 
      End If 

     Next 

    Next 
+0

这段代码可以工作,但它是非常无效的。您正在对每一对进行两次测试,并且针对自己测试每个事件,并且如果您需要它们,还应该在循环外部声明变量。 – 2013-04-28 00:04:52

+0

Hi @SauliusŠimčikas感谢您的评论。你能否提出一个更好的选择,即使在伪代码中?如前所述,我是这方面的新手,并且花了6个小时才弄到这一点。 – Gavin 2013-04-28 00:12:23

+0

我已经在我的答案中做过。我刚刚编辑过,让你更容易理解。 – 2013-04-28 00:38:25