为什么我的 R 递归函数会这样工作?

问题描述 投票:0回答:1

最近读到,对于像 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

r function data-analysis
1个回答
0
投票

您的代码的问题在于,每次迭代返回的 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

© www.soinside.com 2019 - 2024. All rights reserved.