PHP 算法函数
php二分(折半)查找算法函数
根据网上一系列各种函数测试,虽然感觉有些不一样,好歹完成了
/**
* @param $ip_address
* @param $length
* @return bool
* IP段数据文件,每个IP表示成一个10位整数,不足10位的前面补0,比较IP并决定方向
*/
function ip_in_exist($ip_address,$length=10)
{
$datfile = 'ipInt.dat';
$total = floor(filesize($datfile) / $length);
$ipInt = ip2long($ip_address);
$fp = fopen($datfile, 'rb');
$result = binary_search($total, 'compare_ip', $ipInt, $fp);
fclose($fp);
return $result;
}
/**
* @param $total
* @param $callback
* @return bool
* 二分(折半)查找算法
* $args 传参 该数据文件要求: 整值/字符串 需要固定长度 且 按一定顺序排列存放
* 根据总个数不断减半的查询范围查询,起始索引位置由 ip整值 的当前个数与回调返回左右正负数控制
*/
function binary_search($total,$callback)
{
$args = func_get_args();
array_shift($args);
$step = $total;
$offset = 0;
$sign = 1;
do {
$step = ceil($step / 2);
$offset += $sign * $step;
$args[0] = $offset;
$sign = call_user_func_array($callback, $args);
} while ($sign !== 0 && $step > 1);
return $sign === 0;
}
/**
* @param $offset 文件起始指针位置(字节索引)
* @param $ip 转换后比较IP
* @param $fp 文件数据资源
* @return int
*函数binary_search回调函数 返回正负数
*/
function compare_ip($offset, $ip, $fp)
{
fseek($fp, ($offset - 1) * 10);
$checkIp = fread($fp, 10);
$ip = ( strlen($ip)<10 ? str_repeat('0',10-strlen($ip)):'' ).$ip;
$sign = strcmp($ip,$checkIp);
return $sign;
}
空空如也