【问题标题】:Recursive function that calls itself n times without using n as a parameter在不使用 n 作为参数的情况下调用自身 n 次的递归函数
【发布时间】:2011-05-23 06:43:29
【问题描述】:

假设我有 myFunction($var)。它将操纵 $var,在最终返回 $var 之前调用自身 3 次。有没有办法在不存储参数中调用它的次数的情况下做到这一点?

【问题讨论】:

  • 为什么这标记为 php 和语言无关???
  • 也许如果 $var 是什么导致函数精确地递归 3 次。
  • Carlos -- 因为在 php 中可能有一个快捷方式,但这可以由懂任何语言的人提供帮助。 BoltClock-nope,$var 与次数无关,它只是一个被操作的数组,没有引用它
  • 为什么不能在参数中传递它被调用的次数?这将是做到这一点的“正确”方式。

标签: php language-agnostic loops recursion


【解决方案1】:

我想到了两种相互竞争的方法:

  1. 静态全局数据
  2. 转换 $var 以便您可以检测到它被操纵了多少次

【讨论】:

  • 根据上面的 cmets,看起来这些技巧是唯一的方法。如果没有自然的方法可以做到这一点,将接受作为答案
  • “自然方式”?!!脑洞大开!你知道任何语言有“自然的方式”吗?
  • wallyk- 我是一个初级程序员,所以我不太了解递归模式
  • 有一种自然的方式,将n作为参数传递:D
【解决方案2】:

你没有说在递归调用之后会发生什么,所以……

setrlimit(RLIMIT_STACK) 变小值和/或在其他调用中消耗足够的堆栈空间,myFunction() 由于堆栈空间不足而在中止之前只能递归 3 次。

【讨论】:

    【解决方案3】:

    您可以使用静态语句设置一个 var 并在每次进入时检查其值(当然,每次都增加它,当您进入时,在您退出时减少)。 这是一篇关于基本概念的文章。 http://www.bellaonline.com/articles/art29070.asp

    相关代码是

     function count_calls( )
    {
    static $no_calls = 0;
    $no_calls++;
    echo "This function has been called $no_calls times.";
    }
    

    【讨论】:

      【解决方案4】:

      这样做的一种方法是使n 可选,如果未定义则默认为3。我不知道 PHP 语法,但由于它被标记为与语言无关,这里是 javascript 等价物:

      function myFunction (var, n) {
          if (n == undefined) {
              n = 3;
          }
      
          doSomethingWith(var);
      
          n--;
      
          if (n) {
              myFunction(var, n);
          }
      }
      
      // called like this:
      myFunction(someVar);
      

      【讨论】:

      • 不应该是递归部分读取if (n > 0) { myFunction( var n ); } 吗?
      • @Armstrongest:我不希望 n 小于 0。但是,从防御性编程的角度来看,检查 n>0 比检查 n 是否为零(错误)更安全
      • 是的,我明白了...我只是一直觉得依赖 !0 = true 令人不安。一定是我一直在使用具有强类型的语言,例如 C#Java。在代码中明确似乎更好。
      【解决方案5】:

      一些函数式语言支持这种结构。

      例如,在 Mathematica 中,您可以定义:

           f[i_, n_: 3] := Nest[# + 7 &, i, n];  
      

      其中 3 是 n 的默认值。

      所以

           f[2]  
      

      返回

           23  -> (2+7+7+7)
      

           f[4,1]  
      

      返回

           11 (-> 4+7)
      

      当然你也可以定义

           f[i_] := Nest[# + 7 &, i, 3];  
      

      如果您不需要调整递归调用的次数。


      也许这更有趣。您也可以要求所有中间结果。

      所以,如果你定义:

      g[i_, n_: 3] := NestList[# + 7 &, i, n];  
      

      然后

      g[2] Returns {2, 9, 16, 23}  
      

      【讨论】:

        【解决方案6】:

        如果你知道你的函数会精确地调用自己 3 次,其中 调用它的时间是 4 次,那么最好创建一个更简单的非递归函数并明确调用: p>

        simpleF(simpleF(simpleF(simpleF($var))))

        不那么优雅,但更易于维护。

        当然,这不适用于更大的数字。

        【讨论】:

          猜你喜欢
          • 2016-08-06
          • 2013-02-23
          • 2023-03-11
          • 2022-01-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多