Algorithm for counting time that occurred in the same period

I already developed an algorithm for the problem, but I still have problems.

Suppose I have a schedule summary (contained in a gridview named GV):

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

Take a look at the picture below for clearer information: enter image description here

What I want to get from the algorithm is to calculate the time that happened in the same period, for example. during 08.00 there were 46 events (see yellow line).

This is my algorithm:

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

But this led to the wrong value.

The result I want is similar:

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

How to do it right? Actually need your help ...

+2
source share
1 answer

Dictionary, , Key ( ), Value Dictionary.

, , , . , :

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

, 09.40 - 10.00, , , :

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

:

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)

enter image description here

Update

, (TimeRange, TimeRangeCounter 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

, , :

Dim columnLength As Integer = 5
Dim timeStart() As String = {"08.00", "08.00", "10.00", "08.00", "08.00"}
Dim timeEnd() As String = {"08.50", "11.50", "11.00", "09.00", "08.50"}
Dim comparer As New TimeRangeEqualityComparer()
Dim timeRangeCounts As New Dictionary(Of TimeRange, TimeRangeCounter)(comparer)

'Count exact range matches while building dictionary
For i = 0 to columnLength - 1
  Dim key As TimeRange = New TimeRange(timeStart(i), timeEnd(i))

  If timeRangeCounts.ContainsKey(key)
      timeRangeCounts(key).ExactRangeMatch += 1
  Else
      Dim counter =  New TimeRangeCounter()
      counter.ExactRangeMatch = 1
      timeRangeCounts(key) = counter
  End If        

Next           

'Count sub ranges          
For Each kvp in timeRangeCounts
    For Each key in timeRangeCounts.Keys
        If kvp.key.Start >= key.Start AndAlso _ 
           kvp.Key.End <= key.End AndAlso _
           kvp.key.ToString <> key.ToString then           

            kvp.Value.SubRangeMatch += 1
        End If
    Next
Next

Console.WriteLine(timeRangeCounts)
+3

All Articles