这次工作中有用到需要借助GeoIP库来定位ip地址的位置。虽然有自带的函数可以使用。不过经过讨论还是按领导要求用二分法来查找ip。
下面先说下生成的大数组结构。$geoarray={0=>array{startip,endip,cityid},1=>array{startip,endip,cityid},........}
function setGeo(){
$ipnum=bindec(decbin(ip2long($_SERVER['REMOTE_ADDR'])));//ip转整数
$RangB= 0;
$RangE= count($geoarray);
while ($RangB < $RangE-1)
{
//中间数
$RecNo= floor(($RangB + $RangE) / 2);
$val=$geoarray[$RecNo];
if($ipnum == $val[0])
{
$RangB=$RecNo ;
break ;
}
if ($ipnum>$val[0] ){
$RangB= $RecNo;
}
else{
$RangE= $RecNo;
}
}
$val2=$geoarray[$RangB];
if ( ( $val2[0] <= $ipnum ) && ( $val2[1] >= $ipnum ) ){
return $val2[2];
}else{
return '-1';
}
}
最后给个,另外一个二分法,效率没有上面的高,不过理解更方便
function search($array, $k, $low=0, $high=0)
{
if(count($array)!=0 and $high == 0) //判断是否为第一次调用
{
$high = count($array);
}
if($low <= $high) //如果还存在剩余的数组元素
{
$mid = intval(($low+$high)/2); //取$low和$high的中间值
if ($array[$mid] == $k) //如果找到则返回
{
return $mid;
}
elseif ($k < $array[$mid]) //如果没有找到,则继续查找
{
return search($array, $k, $low, $mid-1);
}
else
{
return search($array, $k, $mid+1, $high);
}
}
return -1;
}
$array = array(4,5,7,8,9,10); //测试search函数
echo search($array, 8);