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; 
}

标签: PHP

WeChatPay

微信打赏

Alipay

支付宝打赏

如果对你也有帮助,随便来个五毛的吧,一切随缘看心情...

空空如也