<?php
namespace app\index\controller;
use think\Controller;
use think\Log;
class Index extends Controller
{
public function test($brr = []){
$brr = [[3,10],[7,25],[15,18],[30,40],[25,29]];
$str_arr = [$brr[0]];//此处取$brr数组第一个元素数组
for($i=1;$i<= count($brr)-1;$i++){
/*假设此函数能得到一个二维数组和一个一维数组的交集*/
$str_arr = $this->getLastArr($str_arr,$brr[$i]);
}
print_r($str_arr);
}
/**
* @param $str_arr
* @param $brr
*/
public function getLastArr($str_arr,$brr){
/*此时假设$str_arr是没有交集的二维数组,如[[2,5],[6,10],[11,15]......]
$str_str 是这个二维数组对应的展开,如 [2,5,6,10,11,15.......] */
$str_str = [];
foreach ($str_arr as $v){
foreach ($v as $vl){
$str_str[] =$vl;
}
}
/*假设$brr为一个任意的区间数组如 [12,18]
步骤一 : 把 12拿到 $str_str 中去作对比,找到 12 在 $str_str 中的 哪个区间
步骤二 : 把 15拿到 $str_str 中去对比 ,找到 15 在 $str_str 中的哪个区间
若 12 所在区间的位置数为第m个元素 和 第 n 个元素之间, 15所在区间 为 第x个元素 和 第y个元素之间,
则 m n x y 有四种情况 (m奇数 x奇数 ) 、(m偶数 x奇数 )、
(m奇数 x偶数 ) 、(m偶数 x偶数)
这四种情况的 合并 都有 一定的规律 */
//此函数得到某个数值在数组中区间的位置前一个元素的位置的值 ,$m 表示第 $m个之后
$m = $this->getNum($brr[0],$str_str);
$x = $this->getNum($brr[1],$str_str); //同上
if($m != $x){
//1.(m奇数 x奇数 )
if($m % 2 == 1 && $x % 2 == 1){
//则从 第 $m到 第$x 之间的元素会被合并,且新增 第 $m + 1 和 $m + 2个元素
for($j = $m ;$j<=$x-1;$j++){
unset($str_str[$j]);//出去有交集的部分,
}
}
//2.(m偶数 x奇数 )
if($m % 2 == 0 && $x % 2 == 1){
//则从第 $m 到 第 $x+1 个元素之间的元素会被合并
//为了方便先取出 第 $x+1个元素
$x_1 = $str_str[$x];
for ($j = $m;$j <= $x;$j++){
unset($str_str[$j]);//出去有交集的部分
}
$str_str[$m] = $brr[0];
$str_str[$m+1] = $x_1;
}
//3.(m奇数 x偶数 )
if($m % 2 == 1 && $x % 2 == 0){
//则从第 $m+1 到 第 $x 个元素之间的元素会被合并
//为了方便先取出 第 $m个元素
$x_1 = $str_str[$m-1];
for ($j = $m-1;$j <= $x-1;$j++){
unset($str_str[$j]);//出去有交集的部分
}
$str_str[$m-1] = $x_1;
$str_str[$m] = $brr[1];
}
//4.(m偶数 x偶数 )
if($m % 2 == 0 && $x % 2 == 0){
//则从第 $m 到 第 $x+1 个元素之间的元素会被合并
//为了方便先取出 第 $x+1个元素
for ($j = $m;$j <= $x-1;$j++){
unset($str_str[$j]);//出去有交集的部分
}
$str_str[$m] = $brr[0];
$str_str[$m+1] = $brr[1];
return $str_str;
}
}elseif($m == $x && $m % 2 == 0){
$str_str[$m+1] = $brr[0];
$str_str[$m+2] = $brr[1];
}
$str_str = $this->str_str_arr($str_str);
return $str_str;
}
public function str_str_arr($str_str){
$i=1;
$arr = [];
foreach ($str_str as $key => $vv){
if($i % 2 == 1){
$brr = [];
$brr[] = $vv;
}else{
$brr[] = $vv;
$arr[] = $brr;
}
$i++;
}
return $arr;
}
public function getNum($num,$str_str){
for($i=0;$i<=count($str_str)-2;$i++){ //$i表示 数组中第 $i 个元素
if($num >= $str_str[$i] && $num<= $str_str[$i+1]){
return $i+1;
}elseif($num<$str_str[0]){
return 0;
}
}
return count($str_str);
}
}
合并二维数组交集区间算法
2019-08-29