您的位置:首页 > 编程语言 > PHP开发

合并多段数字区间的解决方案

2014-03-21 14:41 344 查看
场景:
给定N个数字区间,允许选择任意个。
目标:返回合并后的区间。

举个栗子:

给定5个区间如下:

ID                    区间范围
1                      (0,100)
2                      [100,200)
3                      [200,300)
4                      [300,400)
5                      (1000,2000]
6                      (2000,3000]
7                      (3000,+∞)


假设选择的区间为:1、2、4、6、7

则期望返回合并后的区间:

(0,200)
[300,400)
(2000,+∞)


探索出了一个解决方案,欢迎拍砖:

/**
* 合并多段数字区间
* @param array $inputArr 给定的区间ID。 例:
*    array(1,2)
* @param array $intervalArr 区间定义,包括区间ID和数值范围,整个区间必须有下限,可以无上限。 例:
*    array(
*        1 => array(
*            '>' => 0,
*            '<=' => 3000,
*        ),
*        2 => array(
*            '>' => 3000,
*            '<=' => 6000,
*        ),
*        3 => array(
*            '>' => 6000,
*        )
*    )
* @return array $resultArr 返回合并后的区间数组。 例:
*    array(
*        array(
*            '>' => 0,
*            '<=' => 6000
*        )
*    )
*/
public function mergeDigitalInterVal($inputArr, $intervalArr) {
$lastArr = $curArr = $resultArr = array();
// 对给定的区间ID数组按照ID从小到大排序
sort($inputArr);
// 遍历给定的区间ID
foreach ($inputArr as $key => $input) {
$input = intval($input);
if(!isset($intervalArr[$input])) {
continue;
}
$lastUpperArr = $curLowerArr = $lastLowerArr = $curUpperArr = array();
$curArr = $intervalArr[$input]; // 获取当前区间
if($lastArr) { // 如果存在上个区间
$lastUpperArr = array_slice($lastArr, 1, 1); // 获取上个区间的上限
$curLowerArr = array_slice($curArr, 0, 1); // 获取当前区间的下限
if(array_shift($lastUpperArr) == array_shift($curLowerArr)) { // 上个区间和当前区间可合并
$lastLowerArr = array_slice($lastArr, 0, 1); // 获取上个区间的下限
if(count($curArr) > 1) { // 当前区间有上限
$curUpperArr = array_slice($curArr, 1, 1); // 获取当前区间的上限
$lastArr = $lastLowerArr + $curUpperArr; // 上个区间为合并后新的区间
if(($key+1) == count($inputArr)) { // 已经遍历到最后一个
$resultArr[] = $lastArr;
break;
}
$curArr = array();
continue;
} else { // 当前区间没有上限,说明已经遍历到最后一个
$resultArr[] = $lastLowerArr;
break;
}
} else { // 上个区间和当前区间不可合并
$resultArr[] = $lastArr; // 保存上个区间
if(($key+1) == count($inputArr)) { // 已经遍历到最后一个
$resultArr[] = $curArr; // 保存当前区间并退出循环
break;
}
}
} else if(($key+1) == count($inputArr)) { // 不存在上个区间,且已经遍历到最后一个,直接保存当前区间并退出循环
$resultArr[] = $curArr;
break;
}
$lastArr = $curArr;
$curArr = array();
}
return $resultArr;
}


注意此方法需要满足以下约定:
1、相邻区间端点落在同一点上时,包含端点值本身。
2、区间必须有下限(嗯),可以无上限。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数字区间 合并 php