如果您开启了错误报告,您将看到三个这样的提示:
注意:只有变量应该通过引用传递...
这是因为您正在将
array_slice()
的输出作为引用参数传递;要解决此问题,您必须在传递之前将`array_slice()`的输出声明为变量。
事实上,您看到三个提示实际上表明您的递归技术正在按预期遍历并执行工作,但结果元素交换未应用于
$s
上的先前调用 - 换句话说,所有后续递归修改都会丢失。(
演示)
@arkascha在我之前大约一个小时提供了有关您脚本的必要修复,但我可能会稍微不同地编写它。
代码:(演示)
function swapOutermost(&$a) {
$size = count($a);
if ($size > 1) {
$innerElements = array_slice($a, 1, -1);
swapOutermost($innerElements);
$a = array_merge(
[$a[$size - 1]], // last is put first
$innerElements, // recursed reference in the middle
[$a[0]] // first is put last
);
}
}
count()
每次递归调用只执行一次 -- arkascha已经修复了这个问题
- 没有写
return
array_slice()
的第三个参数为-1
与$len - 2
有相同的效果。
这里是一种递归技术,它只使用迭代的count()
调用--没有切片或合并,因为它每次都传递整个原始输入数组。只有目标索引在递归过程中发生变化。我使用对称数组解构(PHP7.1及更高版本可用的工具)根据索引自增进行交换。
代码:(演示)
function swapOutermost(&$a, $i = 0) {
$last = count($a) - 1 - $i;
if ($i < $last) {
[$a[$i], $a[$last]] = [$a[$last], $a[$i]];
swapOutermost($a, ++$i);
}
}
swapOutermost($array);
当然,由于计数不会改变,将其传递一次并重复使用会更有效率。
function swapOutermost(&$a, $count, $i = 0) {
$last = $count - 1 - $i;
if ($i < $last) {
[$a[$i], $a[$last]] = [$a[$last], $a[$i]];
swapOutermost($a, $count, ++$i);
}
}
swapOutermost($array, count($array));
现在,您的原始代码片段使用引用修改,但是您在问题要求中没有明确要求这一点 - 只要使用递归即可。如果您可能会考虑使用递归函数来返回变量(例如,因为您希望能够将此调用嵌套在另一个函数中),那么这里有一种通过每个递归级别传递越来越短的数组的方法(与您的原始方法相同):
代码:(
演示)
function recursiveArrayReverse($a) {
$size = count($a);
if ($size < 2) {
return $a;
}
return array_merge(
[$a[$size - 1]],
recursiveArrayReverse(
array_slice($a, 1, -1)
),
[$a[0]]
);
}
$array = [1, 2, 3, 4, 5, 6, 7];
$array = recursiveArrayReverse($array);
array_slice(...)
,而不是$array_slice(...)
。它是一个函数,不是一个变量。 - arkascha$array_slice
应该从一开始就是array_slice
,你不想在这里使用“可变函数”。 - 04FS