php - 合并相同的ip段算法

查看:59
本文介绍了php - 合并相同的ip段算法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

$arr = array(
    '1.1.1.1_4.1.1.8',
    '2.2.2.1_5.5.5.5',
    '110.1.1.1_194.2.168.1',
    '192.168.1.1_223.233.223.1',
    '192.165.1.2_199.2.2.1',
    '4.4.4.4_6.6.6.6',
    '8.8.8.1_10.1.1.1',
    '8.1.1.1_9.10.10.10',
    '18.1.1.1_19.2.2.2',
    '9.0.0.1_12.9.9.10',
    );
    

$arr中下划线用来间隔一个ip段的,现在要去合并相同的ip段,得到一个新的数组,不考虑子网掩码,例如,1.1.1.1_192.168.1.1,假设有9.9.9.9或者在这之间的都会合并,最后只保留1.1.1.1_192.168.1.1,算法尽可能效率高一些

怕别人没有听明白:举个例子.
1.1.1.1_3.3.3.3
3.2.2.2_6.6.6.6
那么合并后的结果就是:1.1.1.1_6.6.6.6

假设:
1.1.1.1_3.3.3.3
4.4.4.4_6.6.6.6
那么合并后的结果不变,还是这两个,因为中间的段有间隔

解决方案

自己写了个,忽略最后结果重复的问题(这个可以在除重下),谁看看能举出不通过的反例或者提出更好的算法

$arr = array(
    '1.1.1.1_4.1.1.8',
    '2.2.2.1_5.5.5.5',
    '110.3.1.1_194.2.168.1',
    '192.168.1.1_223.233.223.1',
    '192.165.1.2_193.2.2.1',
    '4.4.4.4_6.6.6.6',
    '8.8.8.1_10.1.1.1',
    '8.1.1.1_9.10.10.10',
    '18.1.1.1_19.2.2.2',
    '9.0.0.1_12.9.9.10',
    '195.0.0.1_225.0.0.1',
    '225.0.0.2_225.0.0.111',
    '255.0.0.112_255.0.0.220'
    );



function getIp($ip){
    return bindec(decbin(ip2long($ip)));
}

function trans_to_num($arr){
    $ip_num_arr = [];
    foreach ($arr as $ip_segment) {
        list($startIp,$endIp) = explode('_', $ip_segment);
        $ip_num_arr[getIp($startIp)] = getIp($endIp);
    }
    ksort($ip_num_arr);
    return $ip_num_arr;
}



function merge_ip($arr){
    $merge_arr = [];
    foreach ($arr as $key => $value) {
        $merge_arr[]=['start'=>$key,'end'=>$value];
    }
    $finsh_arr = [];
    $tmp = array_shift($merge_arr);
    foreach ($merge_arr as $k=>$ip_arr) {
        if($ip_arr['start']<$tmp['end'] && $ip_arr['end']<$tmp['end']){
            continue;
        }elseif($ip_arr['start']<$tmp['end'] && $ip_arr['end']>$tmp['end']){
            $tmp['end'] = $ip_arr['end'];
        }else{
            $finsh_arr[]=$tmp;
            $tmp['start'] = $tmp['start'];
            if($ip_arr['start']>=$tmp['end']){
                $tmp['start'] = $ip_arr['start'];    
            }
            $tmp['end'] = max([$ip_arr['end'],$tmp['end']]);
        }
    }
    $finsh_arr[] = $tmp;
    return $finsh_arr;
}

$d = trans_to_num($arr);
$m = merge_ip($d);

echo PHP_EOL;
foreach ($m as $key => $value) {
    echo long2ip($value['start']).'---'.long2ip($value['end']).PHP_EOL;
}

这篇关于php - 合并相同的ip段算法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆