最近读到,对于像 R 这样的函数编程语言,递归优于迭代。我尝试使用一个名为
recur
的函数来实现这一原则,其唯一目的是获取 2 个参数 (x, y)
,增加 x
直到达到 y
,并返回一个向量 x y
。
使用一些print语句检查流程,我发现,虽然程序运行没有错误并且
x
确实增加到y
的值,但最后的return语句产生了不同的输出。这是代码和相应的输出:
recur <- function(x, y) {
# 1st code block
if (x < y) {
print('before') # 1st print statement to check control flow
x <- x + 1
recur(x, y)
}
# 2nd code block
print('return block') # 2nd print statement to check control flow
print('here again') # 3rd print statement to check control flow
return (c(x, y))
}
输出
> recur(0, 5)
[1] "start"
[1] "before"
[1] 1
[1] "start"
[1] "before"
[1] 2
[1] "start"
[1] "before"
[1] 3
[1] "start"
[1] "before"
[1] 4
[1] "start"
[1] "before"
[1] 5
[1] "start"
[1] "return block"
[1] "here again"
[1] "return block"
[1] "here again"
[1] "return block"
[1] "here again"
[1] "return block"
[1] "here again"
[1] "return block"
[1] "here again"
[1] "return block"
[1] "here again"
[1] 1 5
期望的输出
> recur(0, 5)
[1] "start"
[1] "before"
[1] 1
[1] "start"
[1] "before"
[1] 2
[1] "start"
[1] "before"
[1] 3
[1] "start"
[1] "before"
[1] 4
[1] "start"
[1] "before"
[1] 5
[1] "start"
[1] "return block"
[1] "here again"
[1] 5 5
为什么它要迭代第二个代码块,即使该代码块中没有迭代语句?给定输入参数
0, 5
,为什么它返回 1 5
而不是 5 5
?
您的代码的问题在于,每次迭代返回的 x 值并未存储,并且 R 中的变量范围规则导致每次调用 recur 时的 x 都是不同的变量。也就是说,每个 recur() 都有自己的 x,递增 x 不会影响之前调用的 recur() 中 x 的值。第一个 recur() 调用其他递归,但它已经增加了自己的 x,并且不知道其他递归增加了自己的 x。当执行最终的 return 时,该 recur 的 x 仍然是 1,这就是您所看到的。 比较这两个版本的 recur,其中第二个版本存储返回值。
recur <- function(x, y) {
# 1st code block
if (x < y) {
print('before') # 1st print statement to check control flow
x <- x + 1
recur(x, y)
}
# 2nd code block
print(paste('return block', 'x= ',x)) # 2nd print statement to check control flow
print('here again') # 3rd print statement to check control flow
return (c(x, y))
}
recur(0,5)
#> [1] "before"
#> [1] "before"
#> [1] "before"
#> [1] "before"
#> [1] "before"
#> [1] "return block x= 5"
#> [1] "here again"
#> [1] "return block x= 5"
#> [1] "here again"
#> [1] "return block x= 4"
#> [1] "here again"
#> [1] "return block x= 3"
#> [1] "here again"
#> [1] "return block x= 2"
#> [1] "here again"
#> [1] "return block x= 1"
#> [1] "here again"
#> [1] 1 5
recur2 <- function(x, y) {
# 1st code block
if (x < y) {
print(paste('before',x)) # 1st print statement to check control flow
x <- x + 1
x <- recur2(x, y)
}
# 2nd code block
print(paste('return block',x)) # 2nd print statement to check control flow
return (x)
}
recur2(0,5)
#> [1] "before 0"
#> [1] "before 1"
#> [1] "before 2"
#> [1] "before 3"
#> [1] "before 4"
#> [1] "return block 5"
#> [1] "return block 5"
#> [1] "return block 5"
#> [1] "return block 5"
#> [1] "return block 5"
#> [1] "return block 5"
#> [1] 5
创建于 2024 年 11 月 16 日,使用 reprex v2.1.1