回答
不,递归(func_a调用func_a)或间接递归(func_a调用func_b调用func_a)之间的区别在于,使用定时器进行重复调用将会(不耦合)增长堆栈并丢失以前的状态。
在执行尾部呼叫优化的语言中,这在tail-recursion中是正确的。在Scheme中:'(define(move)(set!pos(+ pos 1))(move))'也不会增长堆栈,但它似乎是递归的。正如我在我的回答中所说的那样,在递归和不是的东西之间并没有真正的界限。 – 2010-01-13 07:25:14
否。该函数由外部源(计时器)调用,因此它不是递归的。
不,它*设置*计时器。然后它退出。 – 2010-01-13 07:08:37
这绝对不是递归的。 – ChaosPandion 2010-01-13 07:11:56
不,函数不会调用它自己。如果该函数在移动体内自行调用,它将是递归的。
所以,这里f1(“move”)正在调用f2(“setTimeout”),后者再次调用f1。嗯..这是一个递归,如果f2是一个回调函数。但是,如果F2正在设置一些属性,如“超时”。这不是递归。
它确实取决于您的递归定义,但我会说这是调度一个回调被称为迭代,而不是递归。
递归涉及到将问题分解为更小,类似的问题,直到达到基本案例,然后可能将这些结果合并到解决方案中。这里没有“较小”的问题。它只是安排相同的回调在一定时间后再次发生。
任何种类的硬性和快速定义的问题是递归可以通过迭代来实现,反之亦然。
例如,这是递归吗?
function state1() {
doSomething();
return "state2";
}
function state2() {
doSomethingElse();
return "state1";
}
var state = "state1";
while (true) {
if (state == "state1") {
state = state1();
} else {
state = state2();
}
}
state1
和state1
各自导致另一个被调用;所以从某种意义上说,这是相互递归。它由一个迭代循环驱动,所以它也可以被认为是迭代。
在一种支持尾部优化的语言中,两个函数可以通过递归调用相同的效果(事实上,即使是没有尾部优化的语言,也可以这样做,但是你会用完堆栈空间非常快):
function state1() {
doSomething();
state2();
}
function state2() {
doSomething();
state1();
}
所以,问题真的变成了,你如何区分是否有某种递归?事实上,一个函数导致自己被再次调用使其递归?
我不认为你的例子显示递归,看起来像一个交替调用的简单循环。没有任何状态是树状遍历所需要的,无论您的状态是堆栈还是显式处理。 – stacker 2010-01-13 07:41:59
然而,在一个有尾部呼叫优化的语言(如Scheme)中,它们基本上是等价的;第二个例子实际上并没有在堆栈上有任何状态,因为尾部调用允许你丢弃前一个堆栈帧。因此,在TCO语言中,尾递归解决方案突然停止递归,因为它不会增加堆栈? – 2010-01-13 07:48:30
你让我了解了tail-call,在我看来,这是不必要地使用递归遍历列表,当且仅当你不需要回到以前的位置(这将需要状态)。 BTW的问题被标记为JavaScript相关。 – stacker 2010-01-13 08:24:47
有问题的代码不是递归 - 因为代码被外部调用,而不是作为循环代码路径的一部分返回到相同的方法调用。
维基百科有一个伟大的网页约递归这里:Wikipedia: Recursion (computer science)
是的..但它可以被称为间接递归..
例如对于直接递归会是这样的:
function factorial (n)
{
if(n==0)
{
return(1);
}
return (n * factorial (n-1));
}
也有人说..函数调用本身..
'setTimeout'不会调用'move'。它只是设置'move'在超时到期并返回时被调用。 – 2010-01-13 16:10:25
马修说什么 – 2010-01-27 08:48:10
我把它叫做一个延迟的inifite循环。
当函数返回时,它不会回到它自己的前一个调用实例中,因此没有深层的“调用堆栈”,因为它通常在递归中。
如果函数包含if(pos == 100)dosomething()'?我不认为他是专门针对给定的代码问的。 – 2010-01-13 11:32:29
我认为典型的递归是当你可以说“当这些子任务完成时完成这个任务”。然而,在这种情况下,代码执行它应该做的事情,然后“自行调用”,但没有子任务 - 这是一个循环。代码可能是'while(true){move()} function move(){pos ++}' – naivists 2010-01-13 12:53:01
技术上也可能是......
function move() {
var $this = this;
pos = pos+1;
t = setTimeout($this, 100);
}
,但我看不出有任何理由,你为什么会想这样做。如果你真的想得到傻(并锁定浏览器的线程):
function move() {
var now = +new Date;
pos = pos+1;
while((+new Date - now) <= 100){ }
move();
}
+1谢谢,我只是把清理好的例子放在我的帖子中,因为我不想让人们关注无关码。 – YOU 2010-01-27 08:58:37
- 1. Ackermann函数的这个实现可以称为尾递归吗?
- 2. 这可以递归地完成吗?
- 3. 递归MySql视图:这可能吗?
- 4. 这个递归函数可以疯狂吗?
- 5. 有人可以解释这个递归函数吗?
- 6. 这可以在Prolog中进行尾递归吗?
- 7. 有人可以解释我这种递归吗?
- 8. 这个结果可以通过递归cte来实现吗?
- 9. 可以更有效地编写这种递归吗?
- 10. 递归联合可以优化吗?
- 11. MySQL:表可以递归锁定吗?
- 12. 我可以递归使用“%s”吗?
- 13. 可以回购递归子模块吗?
- 14. 递归DataTemplates可能吗?
- 15. Ruby可以将acts_as_nested_set转换为JSON哈希而不递归吗?
- 16. 可以使用continuations作为递归的替代吗?
- 17. 递归名称
- 18. 所有递归结构都可以被非递归解决方案替代吗?
- 19. 可以函数尾递归
- 20. Java递归 - 这会工作吗?
- 21. 这是Prolog中的左递归吗?
- 22. 是这个函数尾递归吗?
- 23. 我可以传递函数名称作为参数吗?
- 24. 为什么这个递归调用以这种方式工作?
- 25. 我们可以称这个函数为快速排序吗
- 26. 有人可以解释这个递归的JS代码来计算指数吗?
- 27. 这个递归函数不可能迭代吗?
- 28. 有人能为我解释这个递归吗?
- 29. C++ - 递归结构 - 有可能吗?
- 30. 可能有相互递归类吗?
不要把引号的函数名的setTimeout。它绝对不会是递归的,因为函数永远不会被调用,只是引用:-) – 2010-01-13 16:16:45
充其量它可以被称为反复出现:) – 2010-01-26 03:35:39