
本文介绍如何基于一个有序边界数组(如 [200, 400, 600, 800, 1500])构建非重叠连续数值区间,并高效判断多个查询值各自落入哪个区间,适用于分段计费、等级划分、数据归类等场景。
本文介绍如何基于一个有序边界数组(如 [200, 400, 600, 800, 1500])构建非重叠连续数值区间,并高效判断多个查询值各自落入哪个区间,适用于分段计费、等级划分、数据归类等场景。
在实际开发中,我们常需将离散的边界点转化为逻辑连续的范围区间(例如用户积分对应等级、价格区间对应折扣率),再批量判定输入值归属。PHP 原生 range() 函数适合生成小范围整数序列,但对大区间(如 range(801, 1500))会消耗大量内存;更优解是仅存储每个区间的 [start, end] 边界对,并通过二分或线性扫描快速匹配。
以下为完整、健壮且可扩展的 PHP 实现:
<?php
$array1 = [200, 400, 600, 800, 1500]; // 升序边界点(必须已排序)
$array2 = [50, 150, 250, 600, 900, 2000];
$MAX_VALUE = 99999;
// 步骤1:构建区间数组 [[start, end], ...]
$ranges = [];
$prev = 0; // 初始前驱值,用于计算首个区间的起始
foreach ($array1 as $i => $current) {
$start = ($i === 0) ? 1 : $array1[$i - 1] + 1;
$end = $current;
$ranges[] = [$start, $end];
}
// 补充上限区间:[last_boundary + 1, MAX_VALUE]
if (!empty($array1)) {
$last = end($array1);
if ($last < $MAX_VALUE) {
$ranges[] = [$last + 1, $MAX_VALUE];
}
}
// 步骤2:为每个 $array2 元素查找所属区间(线性扫描,O(n×m);大数据量建议改用二分搜索)
$result = [];
foreach ($array2 as $num) {
$found = false;
foreach ($ranges as [$start, $end]) {
if ($num >= $start && $num <= $end) {
$result[] = "$num in $start - $end";
$found = true;
break;
}
}
if (!$found) {
$result[] = "$num out of all defined ranges";
}
}
// 输出结果
echo implode("\n", $result);
// 输出:
// 50 in 1 - 200
// 150 in 1 - 200
// 250 in 201 - 400
// 600 in 401 - 600
// 900 in 801 - 1500
// 2000 in 1501 - 99999
?>✅ 关键设计说明:
- 边界安全:首个区间从 1 开始(而非 0),符合常规业务语义;若需支持 0 或负数,可调整初始 $start。
- 自动补全:自动追加 [last+1, MAX_VALUE] 区间,确保所有大于最大边界的值均有归属。
- 性能提示:当前使用线性匹配,时间复杂度 O(n×m);若 $array1 很大(如 >1000 项)且 $array2 频繁查询,推荐改用 array_search() + 自定义比较函数,或实现二分查找(usort 后 array_filter 配合 current() 快速定位)。
- 健壮性增强:生产环境应添加输入校验(如 is_array(), !empty(), all_integers() 等),避免空数组或非数字输入导致逻辑错误。
? 总结:该方案不依赖内存密集型 range() 数组,仅维护轻量边界对,兼顾可读性、可维护性与运行效率,是处理“数值分段映射”问题的标准实践。

















