算法来计算所发生的同期时间 [英] Algorithm to count the time that occured on the same period

查看:183
本文介绍了算法来计算所发生的同期时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经做了算法的问题,但它仍然有麻烦了。

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆