当两个范围编号重叠时,标识可用的范围编号

时间:2013-05-09 03:23:46

标签: php

如果我有一个现有的范围:

1-10
11-50

然后我将输入1到60的新范围,我怎样才能检测到要添加的新范围与之前的条目重叠?我怎样才能获得可用范围?在这种情况下,可用范围是51-60。

有没有人对此有好主意?

感谢您的帮助。

这是我目前的代码:

$saved = array(
                            array(
                                    "start" => 1,
                                    "end"   => 10
                                ),
                            array(
                                    "start" => 10,
                                    "end"   => 50
                            )
                        );
            $new_range = array(
                                "start" => 1,
                                "end"   => 60
                            );
            $usable_range = array();
            $previous_from = 0;
            $previous_to = 0;
            foreach($saved as $value)
            {
                $range_start = 0;
                $range_end = 0;
                if($previous_from<$value['start'])
                {
                    $previous_from = $value['start'];
                }
                if($previous_to<$value['end'])
                {
                    $previous_to = $value['end'];
                }
                if($previous_from<=$new_range['start'])
                {
                    if($previous_to<$new_range['end'])
                    {
                        $range_start = $previous_to+1;
                        $range_end   = $new_range['end'];
                        $new_range['start'] = $range_start;
                    }
                 }
                else if($previous_from>=$new_range['start'])
                {
                    if($previous_to<$new_range['end'])
                    {
                        $range_start = $previous_to+1;
                        $range_end   = $new_range['end'];
                        $new_range['start'] = $range_start;
                    }
                }
                $usable[] =     array("range_start"=>$range_start,"range_end"=>$range_end);             
            }

2 个答案:

答案 0 :(得分:1)

调用每个间隔(最小,最大)

1)按照min

对间隔列表进行排序

2)检查max是否大于下一个条目min。如果是,则创建一个间隔,该间隔是其分钟中较小的分区和最大分区,并将其添加回列表中以代替这两个分区。

3)每当您获得新的间隔时,二进制搜索到列表中以添加它,按min排序。然后,使用与2)中类似的逻辑,尝试将其与下面的条目和上面的条目合并,直到不再可能合并为止。


编辑:一些变化。

首先,因为我们使用的是整数而不是浮点数,如果你有一个像1,10和11,20这样的区间,那么10和11之间就没有“差距” - 所以我们应该认为这是一个更大的区间,1,20。请反映这一点,而不是检查是否max > next min,如果max >= next min - 1

其次,如果要在将新间隔合并到间隔列表中时找到由重叠形成的所有间隔:

1)由于已知您的间隔列表处于按min排序并按max排序的状态,因此二进制搜索它以找到刚好高于新值的最低分钟最小值和最高值,高于新的最大值

2)在数组中迭代min,max,min,max ...等新的最小值和最大值之间的值。低于最低最低值,高于最高最高值,高于每个最大值/最小值,您可以计算出那里“间隙”的间隔,并将其返回到例如一个数组。


例如,如果您的间隔列表包含13,16,21,24和31,38,并且您想要计算新间隔1,30的非重叠:

1)我们二进制搜索到我们的列表,发现13是最低分数高于1而24是最高分数高于30。

2)我们这样迭代:

  • 在我们的最小和最小分钟之间是1和13 - 所以这形成了间隔1,12(包括底部,独占顶部)。添加到返回数组。
  • 在最大和下一个分钟之间是16和21 - 所以这形成一个间隔17,20(两端都是独占的)。添加到返回数组。
  • 在max和我们的最大值之间是24和30 - 所以这形成一个间隔25,30(独占底部,包括顶部)。添加到返回数组。

答案 1 :(得分:-1)

查找重叠可以描述为找到交叉点。同样地,找到可用范围可以被描述为找到差异。一种方法是将这些集合作为数组并使用array_intersect [1]和array_diff [2]函数。

根据你的详细信息,这就是我所能提出的。

[1] - http://php.net/manual/en/function.array-intersect.php

[2] - http://www.php.net/manual/en/function.array-diff.php