Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 时间范围内任何事件的最大发生次数_Java_Algorithm - Fatal编程技术网

Java 时间范围内任何事件的最大发生次数

Java 时间范围内任何事件的最大发生次数,java,algorithm,Java,Algorithm,我有收集时间戳,例如10:18:07.490,11:50:18.251,其中第一个是事件的开始时间,第二个是事件的结束时间。我需要找到一个最大事件发生时间仅为24小时的范围。这些事件以毫秒为单位发生。 我所做的是以毫秒为单位划分24小时,每毫秒附加一个事件,然后找到一个最大事件发生的范围 LocalTime start = LocalTime.parse("00:00"); LocalTime end = LocalTime.parse("23:59"); for(LocalTime x=s

我有收集时间戳,例如
10:18:07.490,11:50:18.251
,其中第一个是事件的开始时间,第二个是事件的结束时间。我需要找到一个最大事件发生时间仅为24小时的范围。这些事件以毫秒为单位发生。

我所做的是以毫秒为单位划分24小时,每毫秒附加一个事件,然后找到一个最大事件发生的范围

LocalTime start = LocalTime.parse("00:00");
LocalTime end = LocalTime.parse("23:59");

for(LocalTime x=start;x.isBefore(end);x=x.plus(Duration.of millis(1))){
对于(int i=0;i

当然,这不是一个好方法,它需要太多的内存。我怎样才能以正确的方式做这件事?有什么建议吗?

在记忆力方面可以做得更好(好吧,假设O(n)对你来说是好的,你不认为24*60*60*1000是可容忍的常数):

  • 创建项目列表
    [时间,类型]
    (其中时间是时间,类型是 开始或结束)
  • 按时间对列表排序
  • 迭代列表,当看到“开始”时,递增计数器,当看到“结束”时,递减计数器
通过存储“迄今为止看到的最大值”,您可以很容易地识别发生事件最多的单个点

如果要获取包含该点的时间间隔,只需找到“第一个最大值”出现的时间,直到其结束(即下一个
[时间,键入]
pair,或者如果您允许开始、结束在一起且不计数,则从这一点开始仅进行线性扫描,直到计数器减少并移动时间,这只能执行一次,并且不会改变算法的总复杂度)。

修改此方法以获得从点开始的时间间隔非常容易

它可以在内存方面做得更好(假设O(n)对您来说是好的,并且您不认为24*60*60*1000是可容忍的常数):

  • 创建项目列表
    [时间,类型]
    (其中时间是时间,类型是 开始或结束)
  • 按时间对列表排序
  • 迭代列表,当看到“开始”时,递增计数器,当看到“结束”时,递减计数器
通过存储“迄今为止看到的最大值”,您可以很容易地识别发生事件最多的单个点

如果要获取包含该点的时间间隔,只需找到“第一个最大值”出现的时间,直到其结束(即下一个
[时间,键入]
pair,或者如果您允许开始、结束在一起且不计数,则从这一点开始仅进行线性扫描,直到计数器减少并移动时间,这只能执行一次,并且不会改变算法的总复杂度)。
这很容易修改此方法,以获得从点开始的时间间隔

一个找到第一个最大并发事件周期的解决方案: 如果您愿意使用第三方库,可以使用的窗口函数以SQL样式“相对容易”实现。该想法与中所述的相同:

上述印刷品:

Optional[(10:18:07.490, 10:33:17.019, 3)]
所以,在10:18之间。。。10:33…,有3个事件,这是一天中任何时候重叠事件最多的一次

查找最大并发事件的所有时段: 请注意,样本数据中有3个并发事件时,有几个时段
maxBy()
只返回第一个这样的周期。要返回所有此类周期,请改用
maxAllBy()
(添加到jOOλ0.9.11中):

那么:

[(10:18:07.490, 10:33:17.019, 3), 
 (10:37:03.100, 11:00:15.123, 3), 
 (11:20:55.037, 11:50:18.251, 3), 
 (12:15       , 14:13:11.456, 3)]
或者,图形表示 说明: 以下是原始解决方案,并附有注释:

// This is your input data    
Seq.of(tuple(LocalTime.parse("10:18:07.490"), LocalTime.parse("11:50:18.251")),
       tuple(LocalTime.parse("09:37:03.100"), LocalTime.parse("16:57:13.938")),
       tuple(LocalTime.parse("08:15:11.201"), LocalTime.parse("10:33:17.019")),
       tuple(LocalTime.parse("10:37:03.100"), LocalTime.parse("11:00:15.123")),
       tuple(LocalTime.parse("11:20:55.037"), LocalTime.parse("14:37:25.188")),
       tuple(LocalTime.parse("12:15:00.000"), LocalTime.parse("14:13:11.456")))

   // Flatten "start" and "end" times into a single sequence, with start times being
   // accompanied by a "+1" event, and end times by a "-1" event, which can then be summed
   .flatMap(t -> Seq.of(tuple(t.v1, 1), tuple(t.v2, -1)))

   // Sort the "start" and "end" times according to the time
   .sorted(Comparator.comparing(t -> t.v1))

   // Create a "window" between the first time and the current time in the sequence
   .window(Long.MIN_VALUE, 0)

   // Map each time value to a tuple containing
   // (1) the time value itself
   // (2) the subsequent time value (lead)
   // (3) the "running total" of the +1 / -1 values
   .map(w -> tuple(
       w.value().v1,
       w.lead().map(t -> t.v1).orElse(null),
       w.sum(t -> t.v2).orElse(0)))

   // Now, find the tuple that has the maximum "running total" value
   .maxBy(t -> t.v3)
我已经写了更多关于这个问题的文章

(免责声明:我为jOOλ背后的公司工作)

找到第一个最大并发事件周期的解决方案: 如果您愿意使用第三方库,可以使用的窗口函数以SQL样式“相对容易”实现。该想法与中所述的相同:

上述印刷品:

Optional[(10:18:07.490, 10:33:17.019, 3)]
所以,在10:18之间。。。10:33…,有3个事件,这是一天中任何时候重叠事件最多的一次

查找最大并发事件的所有时段: 请注意,样本数据中有3个并发事件时,有几个时段
maxBy()
只返回第一个这样的周期。要返回所有此类周期,请改用
maxAllBy()
(添加到jOOλ0.9.11中):

那么:

[(10:18:07.490, 10:33:17.019, 3), 
 (10:37:03.100, 11:00:15.123, 3), 
 (11:20:55.037, 11:50:18.251, 3), 
 (12:15       , 14:13:11.456, 3)]
或者,图形表示 说明: 以下是原始解决方案,并附有注释:

// This is your input data    
Seq.of(tuple(LocalTime.parse("10:18:07.490"), LocalTime.parse("11:50:18.251")),
       tuple(LocalTime.parse("09:37:03.100"), LocalTime.parse("16:57:13.938")),
       tuple(LocalTime.parse("08:15:11.201"), LocalTime.parse("10:33:17.019")),
       tuple(LocalTime.parse("10:37:03.100"), LocalTime.parse("11:00:15.123")),
       tuple(LocalTime.parse("11:20:55.037"), LocalTime.parse("14:37:25.188")),
       tuple(LocalTime.parse("12:15:00.000"), LocalTime.parse("14:13:11.456")))

   // Flatten "start" and "end" times into a single sequence, with start times being
   // accompanied by a "+1" event, and end times by a "-1" event, which can then be summed
   .flatMap(t -> Seq.of(tuple(t.v1, 1), tuple(t.v2, -1)))

   // Sort the "start" and "end" times according to the time
   .sorted(Comparator.comparing(t -> t.v1))

   // Create a "window" between the first time and the current time in the sequence
   .window(Long.MIN_VALUE, 0)

   // Map each time value to a tuple containing
   // (1) the time value itself
   // (2) the subsequent time value (lead)
   // (3) the "running total" of the +1 / -1 values
   .map(w -> tuple(
       w.value().v1,
       w.lead().map(t -> t.v1).orElse(null),
       w.sum(t -> t.v2).orElse(0)))

   // Now, find the tuple that has the maximum "running total" value
   .maxBy(t -> t.v3)
我已经写了更多关于这个问题的文章


(免责声明:我为jOOλ背后的公司工作)

为什么这样的计算会减少4GB内存。只有8.64e7个元素。为什么要将它们添加到列表中?无法满足“开始>x”和“结束x和end“查找最大事件发生的范围”@vish4071因此,获取“第一次最大事件”发生之间的时间间隔,直到其结束(即下一次[时间,键入]配对,或者如果允许开始、结束在一起且不计数,则从这一点开始仅进行线性扫描,直到计数器减少并移动时间,这只能执行一次,并且不会改变算法的总复杂度)。修改此方法以获得从点开始的间隔非常容易。我很想看到在
O(N)
中执行的实际算法。看来这个解决方案
// This is your input data    
Seq.of(tuple(LocalTime.parse("10:18:07.490"), LocalTime.parse("11:50:18.251")),
       tuple(LocalTime.parse("09:37:03.100"), LocalTime.parse("16:57:13.938")),
       tuple(LocalTime.parse("08:15:11.201"), LocalTime.parse("10:33:17.019")),
       tuple(LocalTime.parse("10:37:03.100"), LocalTime.parse("11:00:15.123")),
       tuple(LocalTime.parse("11:20:55.037"), LocalTime.parse("14:37:25.188")),
       tuple(LocalTime.parse("12:15:00.000"), LocalTime.parse("14:13:11.456")))

   // Flatten "start" and "end" times into a single sequence, with start times being
   // accompanied by a "+1" event, and end times by a "-1" event, which can then be summed
   .flatMap(t -> Seq.of(tuple(t.v1, 1), tuple(t.v2, -1)))

   // Sort the "start" and "end" times according to the time
   .sorted(Comparator.comparing(t -> t.v1))

   // Create a "window" between the first time and the current time in the sequence
   .window(Long.MIN_VALUE, 0)

   // Map each time value to a tuple containing
   // (1) the time value itself
   // (2) the subsequent time value (lead)
   // (3) the "running total" of the +1 / -1 values
   .map(w -> tuple(
       w.value().v1,
       w.lead().map(t -> t.v1).orElse(null),
       w.sum(t -> t.v2).orElse(0)))

   // Now, find the tuple that has the maximum "running total" value
   .maxBy(t -> t.v3)