PHP 获取指定范围内最接近数的算法实现

小石头
小石头
发布时间:2026-10-13| 4人浏览过
原创

本文介绍了在 PHP 中如何计算并获取指定范围内最接近的基准数值的方法,包含针对固定步长的取整逻辑以及从离散数组中查找最近值的通用解法。

场景需求与核心逻辑

在处理分页、数据分组、时间戳对齐或量化指标时,我们经常需要将一个任意数值“吸附”到特定的规则网格上。例如,用户输入了 44,要求按照每 10 个一组进行对齐,结果应该是 40 还是 50?这取决于业务是要求“最接近”、“强制向上”还是“强制向下”。此外,当可用选项不是连续间隔而是离散的数组(如商品规格 [3, 8, 19])时,也需要特殊的查找逻辑。

固定步长下的最近数计算

对于有明确步长(Range)的情况,核心思路是利用模运算(%)求出余数,再通过比较余数大小或使用内置取整函数决定进位方向。

第1步:获取双向最接近值 (NextRelatedNumber)

此函数用于返回距离目标数值最近的基准数。如果正好处于两个基准数的中间,默认情况下倾向于向高位进位(具体行为取决于四舍五入规则)。

  • 入口参数:$number (目标数值), $range (步长)。
  • 操作原理:先通过 round($r / $range, 0) 判断余数占比,若大于等于 0.5 则进位。
// 返回最接近的下一个或前一个基准数
function NextRelatedNumber($number, $range){
  $r = $number % $range;
  $f = $number - $r;
  $b = round($r / $range, 0);
  return ($b == 1) ? $f + $range : $f; 
}

第2步:强制向上对齐 (NextHigherNumber)

无论余数多小,只要不为 0,就向更大的基准数靠拢。适用于需要预留余量的场景。

  • 操作原理:使用 ceil() 向上取整。
// 返回下一个更高的基准数
function NextHigherNumber($number, $range){
  $r = $number % $range;
  $f = $number - $r;
  $b = ceil($r / $range);
  return ($b == 1) ? $f + $range : $f; 
}

第3步:强制向下对齐 (NextLowerNumber)

舍弃余数部分,始终向更小的基准数靠拢。适用于截断或向下取整场景。

  • 操作原理:使用 floor() 向下取整。
// 返回下一个更低的基准数
function NextLowerNumber($number, $range){
  $r = $number % $range;
  $f = $number - $r;
  $b = floor($r / $range);
  return ($b == 1) ? $f + $range : $f; 
}

从离散数组中查找最接近值

当可选范围不是一个均匀的数列,而是一个具体的数组(如 [3, 8, 19, 34])时,简单的取模无法解决问题。我们需要遍历数组,计算每个元素与目标值的绝对差值,并记录最小差值对应的索引。

第4步:遍历查找最近邻 (NextNumberArray)

  • 入口参数:$Number (目标值), $NumberRangeArray (候选数组)。
  • 关键状态:$c 记录当前发现的最小差值,$w 记录对应元素的索引。
  • 初始化:由于首次循环尚未比较,需手动设置初始状态或特殊标记。
// 从数组中返回与目标数值最接近的那个数
function NextNumberArray($Number, $NumberRangeArray){
  $w = 0;
  $c = -1; // 标记为未初始化
  $abstand = 0;
  $l = count($NumberRangeArray);    
  for($pos=0; $pos < $l; $pos++){
    $n = $NumberRangeArray[$pos];
    // 计算绝对差值
    $abstand = ($n < $Number) ? $Number - $n : $n - $Number;
    
    if ($c == -1){
      $c = $abstand;
      continue;
    }
    else if ($abstand < $c){
      $c = $abstand;
      $w = $pos;
    }
  }
  return $NumberRangeArray[$w];
}

测试用例与结果验证

以下是上述函数的实际运行效果,帮助理解不同场景下的输出:

  1. 双向最近匹配:
    目标 44,步长 10。
    逻辑:余数 4 小于 5,不进位。
    结果:40。
  2. 向上对齐:
    目标 41,步长 20。
    逻辑:余数 1,向上取整后进位到下一个周期。
    结果:60(注意:原代码逻辑中 `ceil(1/20)=1`,触发 `$f + $range`,即 `20+20=40`? 此处需注意原代码逻辑细节:`$f`是基准低位,`$range`是步长。若 `ceil` 为1,说明有余数,应加上一段步长。但在本例 `41 % 20 = 1`, `$f=40`, `$b=ceil(0.05)=1`, 返回 `40+20=60`。这个逻辑是针对“下一个周期开始处”的对齐,而非简单的向上取整到最近的倍数。需根据实际需求确认是否适用)。
  3. 向下对齐:
    目标 57,步长 5。
    逻辑:余数 2,直接截断。
    结果:55。
  4. 数组最近查找:
    目标 45,数组 [3, 8, 19, 34, 56, 89]。
    对比:|45-34|=11, |45-56|=11。由于代码中使用 `<` 严格小于,前者会保留在 $w,后者不会更新。
    结果:34(同为11差距时,优先选择先遇到的较小值)。

以上就是PHP获取指定范围内最接近数的详细功能介绍,更多关于PHP编程技巧和算法优化的资料请关注本站其它相关文章!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。