0

我正在编写一个时间表代码。我正在使用与这些模块相关的大学模块和事件系统,即

模块 CSC3039 Event1 - Lecture Event2 - Lecture Event3 - Practical 等

我需要检查模块中每个事件的时间并比较冲突。冲突不需要纠正,只需突出显示即可。我将使用的表Events包含Event_ID (PK), Module_code (FK), Start_Date_Time, End_Date_Time其他无关紧要的字段。我发现我需要实现一个For Each语句,最终导致一个 if 语句,例如:

if (startTime1 <= endTime2 或 endTime1 >= startTime2) 冲突

我的问题是试图在这里找出实际的 for 循环。我不知道该写什么来声明我的开始时间和结束时间。我认为这是获取 event1 并获取其开始和结束然后检查事件 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

尝试将事件添加到我的数组列表时,我注意到在调试中没有事件发送到列表。

4

3 回答 3

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
于 2013-04-27T23:03:41.690 回答
0

我的比较来自数据库。在下面的代码之前,我有一个查询,它Events根据用户输入的 a 来返回我的表中的所有记录Module_Code。此代码将通过 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
于 2013-04-27T23:55:23.733 回答
0

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

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

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

于 2013-04-27T23:29:13.247 回答