阶梯访问表优化

之前在 Code complete 中读到了阶梯访问表的概念 , 写出了第一版直接遍历的函数把老项目里的各种 if else 费率判断清了个干净 .

阶梯访问表适合用在区间大小不固定的情况 , 如利息根据额度变化的需求

/**
 * 阶梯访问表 l 左边界 r右边界 v 取值
 * $table = [
 * ['l' => 1500, 'r' => 1500, 'v' => '0.23'],
 * ['l' => 2000, 'r' => 2000, 'v' => '0.25'],
 * ['l' => 2500, 'r' => 2500, 'v' => '0.29'],
 * ['l' => 2700, 'r' => 5000, 'v' => '0.30'],
 * ['l' => 5500, 'r' => 7000, 'v' => '0.50'],
 * ]
 * stairStepAccess($table , 2900) ; // 0.30
 *
 *
 * @param array $table 查找表
 * @param mixed $target 查找的目标数据
 * @return mixed
 * @throws Exception
 */
function stairStepAccessIterate($table, $target)
{
    foreach ($table as $row) {
        if ($row['l'] <= $target && $target <= $row['r']) {
            return $row['v'];
        }
    }

    throw new \Exception('stairStepAccess overflow '.$target);
}

然后呢最近每天都有做一道算法题 , 自然而然的就开始思考起如何优化这个简单的函数 , 大部分情况下表都是顺序排列的, 所以使用了二分查找重写了中间部分代码


 * 阶梯访问表 l 左边界 r右边界 v 取值
 * $table = [
 * ['l' => 1500, 'r' => 1500, 'v' => '0.23'],
 * ['l' => 2000, 'r' => 2000, 'v' => '0.25'],
 * ['l' => 2500, 'r' => 2500, 'v' => '0.29'],
 * ['l' => 2700, 'r' => 5000, 'v' => '0.30'],
 * ['l' => 5500, 'r' => 7000, 'v' => '0.50'],
 * ]
 * stairStepAccess($table , 2900) ; // 0.30
 * 
 * 
 * @param array $table 查找表 
 * @param mixed $target 查找的目标数据 
 * @return mixed
 * @throws Exception
 */
function stairStepAccess($table, $target)
{
    $l = 0;
    $r = count($table) - 1;
    while ($l <= $r) {
        $mid = (int)(($l + $r) / 2);
        if ($table[$mid]['l'] <= $target && $target <= $table[$mid]['r']) {
            return $table[$mid]['v'];
        }
        if ($target > $table[$mid]['r']) {
            $l = $mid + 1;
        } else {
            $r = $mid - 1;
        }
    }
    throw new \Exception('stairStepAccess overflow value ' . $target);
}

生成了有 90 万条数据的表 , 进行 100 万次查询后的性能简单对比

阶梯访问表 PHP 函数

完结撒花 , 算法撒浪嘿

PS : 寻求有挑战的工作机会中 , 欢迎联系

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!