算法来计算所发生的同期时间 [英] Algorithm to count the time that occured on the same period
问题描述
我已经做了算法的问题,但它仍然有麻烦了。
I have already made an algorithm for the problem but it still got a trouble.
假设我有计划的回顾(包含GridView控件名为GV):
Suppose that I have the recap of schedule (contains on gridview named GV):
TimeStart TimeEnd TotalOccuredOnThisTime
----------------------------------------------
08.00 08.50 1
08.00 09.40 43
08.00 10.50 2
请看看下面的图片为更加清晰的信息:
Pls take a look to the picture below for more clear information:
我想从算法得到的是,计算所发生在同一时期的时间,如在08.00的时候,它的发生46事件(见黄色行)。
What I want to get from the algorithm is, to count the time that occured on the same period, e.g. on the time of 08.00, it's occured 46 event (see the yellow colored row).
这是我的算法:
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 it's resulted the wrong value.
我要的结果是这样的:
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 that properly? Really need your help...
推荐答案
您可以使用的 词典
通过连接这两个时间串在一起的键跟踪时间范围
(无须转换为整数),然后针对这个范围,你可以递增词典的
。值
部分的每一次出现
You can use a Dictionary
to keep track of the time ranges by concatenating the two time strings together for the Key
(no need to cast to integers), and then for each occurrence of that range you could increment the Value
portion of the Dictionary
.
此外,也没有必要在使用这种方法,或分段环来填充开始和结束时间的阵列嵌套循环。下面的算法应该提供你正在寻找的结果:
Additionally, there is no need to have nested loops using this approach, or a staging loop to populate start and end time arrays. The following algorithm should provide the results you are looking for:
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,例如,从字典:
Thus you could pull the count of the time range 09.40 - 10.00, for example, from the dictionary by saying:
Dim totalOccuredOnThisTime As Integer = timeRangeCount("09.40-10.00")
我有验证该算法与同类测试code:
I've verified this algorithm with the similar test code:
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)
在读你澄清你的意见,你仍然可以使用字典来帮助跟踪这与一对夫妇的辅助类(沿<$ C C $> TIMERANGE , TimeRangeCounter
和 TimeRangeEqualityComparer
)。这确实让事情变得更复杂一点,但。
After reading your clarification in your comment, you can still use the Dictionary to help keep track of this along with a couple helper classes (TimeRange
, TimeRangeCounter
, and TimeRangeEqualityComparer
). This does make things a bit more complicated though.
第一辅助类是用来装准确和子范围匹配的计数:
The first helper class is used to hold the counts of exact and sub range matches:
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
第三辅助类存储范围的开始和结束时间:
The Third helper class stores the start and end times of a range:
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
因此,使用上面我们应该能写出这种算法:
So using the above we should be able to write this algorithm:
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)
这篇关于算法来计算所发生的同期时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!