PHP按指定间隔合并两个数组的功能实现需求
嘿,我来帮你实现这个array_merge_interval函数!结合PHP的数组特性和简单的循环逻辑,我们可以写出清晰且符合需求的代码,避免复杂的嵌套循环。
需求回顾
我们需要实现一个函数array_merge_interval($arr1, $arr2, $x, $y),按照以下规则合并两个数组:
- 循环执行:从
$arr1取$x个元素(元素不足时从头循环取),再从$arr2取$y个元素(同样循环取)。 - 停止条件:当所有需要取的元素都已包含在结果中——即如果
$x>0则$arr1的所有元素都要被包含;如果$y>0则$arr2的所有元素都要被包含;若某数组不需要取元素(对应参数为0),则无需包含其元素。
实现代码
function array_merge_interval(array $arr1, array $arr2, int $x, int $y): array { $result = []; // 处理边界情况:都不取元素 if ($x === 0 && $y === 0) { return $result; } $count1 = count($arr1); $count2 = count($arr2); // 标记是否需要收集对应数组的所有元素 $needCollect1 = $x > 0; $needCollect2 = $y > 0; // 用翻转数组来跟踪已收集的元素(键为元素,值用于标记) $collected1 = $needCollect1 ? array_flip($arr1) : []; $collected2 = $needCollect2 ? array_flip($arr2) : []; $remaining1 = count($collected1); // 剩余需要收集的arr1元素数量 $remaining2 = count($collected2); // 剩余需要收集的arr2元素数量 $index1 = 0; $index2 = 0; // 循环直到所有需要收集的元素都已收集完成 while ($remaining1 > 0 || $remaining2 > 0) { // 从arr1取x个元素 for ($i = 0; $i < $x && ($remaining1 > 0 || $remaining2 > 0); $i++) { if ($count1 === 0) break; // 空数组直接跳过 $element = $arr1[$index1 % $count1]; $result[] = $element; // 如果该元素还未被收集,标记为已收集 if ($needCollect1 && isset($collected1[$element])) { unset($collected1[$element]); $remaining1--; } $index1++; // 检查是否所有需要收集的元素都已完成,是的话直接跳出所有循环 if ($remaining1 === 0 && $remaining2 === 0) { break 2; } } // 从arr2取y个元素 for ($i = 0; $i < $y && ($remaining1 > 0 || $remaining2 > 0); $i++) { if ($count2 === 0) break; // 空数组直接跳过 $element = $arr2[$index2 % $count2]; $result[] = $element; // 如果该元素还未被收集,标记为已收集 if ($needCollect2 && isset($collected2[$element])) { unset($collected2[$element]); $remaining2--; } $index2++; // 检查是否所有需要收集的元素都已完成,是的话直接跳出所有循环 if ($remaining1 === 0 && $remaining2 === 0) { break 2; } } } return $result; }
代码关键点说明
- 边界处理:先处理
$x和$y都为0的情况,直接返回空数组;同时处理空输入数组的情况,避免取模错误。 - 收集跟踪:用
array_flip将原数组转为元素为键的数组,这样可以快速判断元素是否已被收集(isset操作是O(1)),并通过remaining1和remaining2跟踪剩余需要收集的元素数量。 - 循环取元素:通过
$index % count($arr)的方式实现循环取数,不需要额外复制数组,简洁高效。 - 停止条件:每次添加元素后检查是否所有需要收集的元素都已完成,一旦完成直接跳出所有循环,避免不必要的迭代。
测试示例
我们来验证你给出的几个示例:
// 示例1:2个A、1个B循环 $arrA = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']; $arrB = [1, 2, 3, 4]; print_r(array_merge_interval($arrA, $arrB, 2, 1)); // 输出:Array ( [0] => A [1] => B [2] => 1 [3] => C [4] => D [5] => 2 [6] => E [7] => F [8] => 3 [9] => G [10] => H [11] => 4 ) // 示例2:2个B、1个A循环 print_r(array_merge_interval($arrB, $arrA, 2, 1)); // 输出:Array ( [0] => 1 [1] => 2 [2] => A [3] => 3 [4] => 4 [5] => B [6] => 1 [7] => 2 [8] => C [9] => 3 [10] => 4 [11] => D [12] => 1 [13] => 2 [14] => E [15] => 3 [16] => 4 [17] => F [18] => 1 [19] => 2 [20] => G [21] => 3 [22] => 4 [23] => H ) // 示例3:6个B、0个A print_r(array_merge_interval($arrB, $arrA, 6, 0)); // 输出:Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 ) // 示例4:20个A、3个B print_r(array_merge_interval($arrA, $arrB, 20, 3)); // 输出与你给出的结果完全一致
内容的提问来源于stack exchange,提问作者powerbuoy
相关产品推荐
相关产品推荐

