PHP重叠事件的阵列获取的正常运行时间
问题描述:
解决方案:PHP重叠事件的阵列获取的正常运行时间
我看了看这个: Merging overlapping ranges in PHP arrays?
,并解决了我在这个例子中的问题: https://3v4l.org/XCtlT
非工作代码例如这里: https://3v4l.org/sStTT
从本质上讲,我有重叠的停机事件,看起来像这样的数组:
$incidents = [
['start' => '2016-01-05 00:00:00', 'end' => '2016-01-10 23:59:59'],
['start' => '2016-01-07 00:00:00', 'end' => '2016-01-15 23:59:59'], // overlapping
['start' => '2016-01-12 00:00:00', 'end' => '2016-01-13 23:59:59'], // overlapping
['start' => '2016-01-20 00:00:00', 'end' => '2016-01-25 23:59:59'],
['start' => '2016-01-23 00:00:00', 'end' => '2016-01-24 23:59:59'] // overlapping
];
而且从事故阵列我期望得到下面的结果作为一个正常运行阵列。
Array
(
[0] => Array
(
[start] => 2016-01-01 00:00:00
[end] => 2016-01-05 00:00:00
)
[1] => Array
(
[start] => 2016-01-15 23:59:59
[end] => 2016-01-20 00:00:00
)
[2] => Array
(
[start] => 2016-01-25 23:59:59
[end] => 2016-01-31 23:59:59
)
)
不幸的是,我的逻辑游戏不够好,足以完成可靠而高效的任务。在我的例子中,我有大约250万行数据库中的事件。
你对使用2 for循环来计算正常运行时间的想法?
是否有更有效的/更简单的方法来做到这一点?
您能够完成逻辑,正常运行时间的结果如预期运行?
答
有四个步骤,以这样的算法:
- 筛选事件那些重叠的报告日期范围
- 排序事件的事件开始
- 全部合并事件为连续的块(
O(n)
操作) - 通过返回合并事件之间的间隔来反转这些范围(
O(n)
操作)
步骤1和2可以在数据库中查询被简单处理,如:
select start, end
from incidents
where start < :reportEnd and
end > :reportStart
order by start
要注意的一点:如果可能的话,你真的应该考虑使用[开始,结束)格式的日期时间范围内(含开始,独家结束)。当试图解决'2016-01-25 00:00:00 - > 2016-01-25 23:59:59'与'2016-01-26 00:00:'连续时,它会使算法变得更简单。 00 - > 2016-01-26 23:59:59'。 – Phylogenesis