计算同一时期发生的时间的算法

时间:2012-04-02 11:43:57

标签: vb.net algorithm

我已经针对这个问题制定了一个算法,但它仍然遇到了麻烦。

假设我有一个时间表的回顾(包含在名为GV的gridview上):

TimeStart  TimeEnd   TotalOccuredOnThisTime
----------------------------------------------
08.00      08.50     1
08.00      09.40     43
08.00      10.50     2

请查看下面的图片以获取更清晰的信息: enter image description here

我想从算法得到的是计算同一时期发生的时间,例如在08.00的时间,它发生了46事件(见黄色行)。

这是我的算法:

Dim ColumnLength As Integer = GV.Rows.Count
Dim TimeStart(ColumnLength - 1) As Integer
Dim TimeEnd(ColumnLength - 1) As Integer
Dim Total(ColumnLength - 1) As Integer

For i = 0 to ColumnLength - 1
  TimeStart(i) = Convert.ToInt32(Regex.Replace(GV.Rows(i).Cells(0).Text, ".", ""))
  TimeEnd(i) = Convert.ToInt32(Regex.Replace(GV.Rows(i).Cells(1).Text, ".", ""))
  Total(i) = 0
Next 

For i = 0 To ColumnLength - 2
  For j = 0 To ColumnLength - 1        
    If TimeEnd(i) > TimeStart(j) And ((TimeStart(i) <= TimeEnd(j)) Or (TimeStart(i) >= TimeEnd(j))) 
      Total(j) = Total(j) - Total(i)
    End If
  Next
Next

但这导致错误的价值。

我想要的结果是:

Time: 08.00 - 08.50   --> 46 event occured
      08.50 - 09.40   --> 46 event occured
      09.40 - 10.00   --> 45 event occured
      etc...

如何正确地做到这一点?真的需要你的帮助......

1 个答案:

答案 0 :(得分:3)

您可以使用Dictionary通过将Key的两个时间字符串连接在一起来跟踪时间范围(不需要转换为整数),然后对于该范围的每次出现您可以增加Value的{​​{1}}部分。

此外,不需要使用此方法嵌套循环,也不需要使用分段循环来填充开始和结束时间数组。以下算法应提供您要查找的结果:

Dictionary

因此,您可以通过以下方式从字典中提取时间范围09.40 - 10.00的计数:

Dim columnLength As Integer = GV.Rows.Count
Dim timeRangeCount As New Dictionary(Of String, Integer)

For i = 0 to columnLength - 1
  Dim timeStart As String = GV.Rows(i).Cells(0).Text
  Dim timeEnd As String = GV.Rows(i).Cells(1).Text
  Dim key As String = String.Format("{0}-{1}", timeStart, timeEnd)

  If timeRangeCount.ContainsKey(key)
      timeRangeCount(key) += 1
  Else
      timeRangeCount(key) = 1
  End If
Next

我已使用类似的测试代码验证此算法:

Dim totalOccuredOnThisTime As Integer = timeRangeCount("09.40-10.00")

enter image description here

更新

在您的评论中阅读了您的说明后,您仍然可以使用词典来帮助跟踪这一点以及几个辅助类(Dim columnLength As Integer = 6 Dim timeStart() As String = {"08.00", "08.00", "10.00", "08.00", "08.00", "10.00"} Dim timeEnd() As String = {"08.50", "08.50", "11.00", "09.00", "08.50", "11.00"} Dim timeRangeCount As New Dictionary(Of String, Integer) For i = 0 to columnLength - 1 Dim key As String = String.Format("{0}-{1}", timeStart(i), timeEnd(i)) If timeRangeCount.ContainsKey(key) timeRangeCount(key) += 1 Else timeRangeCount(key) = 1 End If Next Console.WriteLine(timeRangeCount) TimeRangeTimeRangeCounter)。这确实使事情变得复杂一些。

第一个辅助类用于保存精确匹配和子范围匹配的计数:

TimeRangeEqualityComparer

第二个辅助类用于帮助字典知道一个密钥(类型Public Class TimeRangeCounter Property ExactRangeMatch as Integer Property SubRangeMatch as Integer End Class )与另一个密钥的区别:

TimeRange

第三个助手类存储范围的开始和结束时间:

Public Class TimeRangeEqualityComparer 
    Implements IEqualityComparer(Of TimeRange)

    Public Overloads Function Equals(left As TimeRange, right As TimeRange) _
            As Boolean Implements IEqualityComparer(Of TimeRange).Equals           

        Return left.ToString = right.ToString   
    End Function

    Public Overloads Function GetHashCode(range As TimeRange) _
            As Integer Implements IEqualityComparer(Of TimeRange).GetHashCode

        return range.ToString().GetHashCode()
    End Function

End Class

所以使用上面我们应该能够编写这个算法:

Public Class TimeRange 
    Private readonly _start
    Private readonly _end

    Public Readonly Property Start 
        Get
           return _start
        End Get
    End Property

    Public Readonly Property [End] 
        Get
           return _end
        End Get
    End Property

    Public Sub New(start As String, [end] As string)
        Me._start = start
        Me._end = [end]
    End Sub

    Public Overrides Function ToString() as String
       Return String.Format("{0}-{1}", Start, [End])
    End Function

End Class