它是正确的说是无处不在recursion
使用的一个for循环可以用吗? 如果递归通常慢是什么技术上的原因永远使用它在for循环迭代?
而如果它总是可以的递归转换成一个for循环是有这样做的拇指方式的规则?
它是正确的说是无处不在recursion
使用的一个for循环可以用吗? 如果递归通常慢是什么技术上的原因永远使用它在for循环迭代?
而如果它总是可以的递归转换成一个for循环是有这样做的拇指方式的规则?
递归通常要慢得多,因为所有的函数调用必须存储在堆栈中,以允许返回到调用函数。 在许多情况下,内存有被分配并复制到实施范围的隔离。
一些优化,比如尾部调用优化 ,使递归更快,但并不总是可能的,而不是在所有语言中实现。
主要原因使用递归的
当然,每一个递归可模拟为一种循环:这就是CPU将最终做。 和递归本身,更直接,意味着投入堆栈中的函数调用和范围。 但是,改变你的递归算法的一个循环,可能需要大量的工作,使你的代码少维护:为每一个优化的,它应该只尝试当一些分析或证据表明它是必要的。
它是正确的说是无处不在递归使用的一个for循环可以用吗?
是的,因为在大多数的CPU递归建模与循环和堆栈数据结构。
如果递归通常慢是什么技术原因使用它?
这不是“通常慢”:它是被错误地应用这是较慢的递归。 最重要的是,现代的编译器善于把一些递归到循环,甚至没有要求。
而如果它总是可以的递归转换成一个for循环是有这样做的拇指方式的规则?
写反复解释时,最好的理解算法迭代方案; 写递归算法最好的解释递归程序。
例如,在许多编程语言搜索二叉树,运行快速排序,并解析表达式往往是递归的解释。 这些都是最好的递归编码为好。 在另一方面,计算阶乘和计算斐波那契数更容易在迭代来解释。 使用递归对他们来说就像是用大锤乱打苍蝇:这不是一个好主意,即使大锤做了很好的工作吧+。
如果递归通常慢是什么技术上的原因永远使用它在for循环迭代?
因为在一些算法是很难迭代求解。 尽量在这两个递归迭代和解决深度优先搜索。 你会得到的想法,这是普通的难以解决的DFS与迭代。
另一件好事尝试:尝试编写合并排序迭代。 它会带你相当长的一段时间。
它是正确的说是无处不在递归使用的一个for循环可以用吗?
是。 该线程有这个很好的答案。
而如果它总是可以的递归转换成一个for循环是有这样做的拇指方式的规则?
相信我。 尝试写自己的版本迭代求解深度优先搜索。 你会发现,有些问题更容易解决递归它。
提示:递归是好的,当你解决了可以通过解决的问题分而治之的技术。
除了是较慢的,递归也可以根据它去有多深导致堆栈溢出错误。
编写使用迭代等效的方法,我们必须明确地使用堆栈。 该迭代版本,要求其解决方案堆栈的事实表明,这个问题是相当困难的,它可以从递归受益。 作为一般规则,递归最适合于不能用固定的内存量来解决,迭代求解时因此需要堆叠的问题。 话虽如此,递归和迭代可以表现出同样的结果,而他们遵循不同的pattern.To决定哪种方法更好地情况的情况下,最好的做法是选择基于这个问题遵循的模式。
例如,为了找到三角序列的第n个三角数:1 3 6 10 15 ...使用迭代算法来寻找第n个三角数的程序:
使用迭代算法:
//Triangular.java
import java.util.*;
class Triangular {
public static int iterativeTriangular(int n) {
int sum = 0;
for (int i = 1; i <= n; i ++)
sum += i;
return sum;
}
public static void main(String args[]) {
Scanner stdin = new Scanner(System.in);
System.out.print("Please enter a number: ");
int n = stdin.nextInt();
System.out.println("The " + n + "-th triangular number is: " +
iterativeTriangular(n));
}
}//enter code here
使用递归算法:
//Triangular.java
import java.util.*;
class Triangular {
public static int recursiveTriangular(int n) {
if (n == 1)
return 1;
return recursiveTriangular(n-1) + n;
}
public static void main(String args[]) {
Scanner stdin = new Scanner(System.in);
System.out.print("Please enter a number: ");
int n = stdin.nextInt();
System.out.println("The " + n + "-th triangular number is: " +
recursiveTriangular(n));
}
}
大部分的答案似乎认为iterative
= for loop
。 如果你的循环是不受限制的( 一拉 C,你可以做你想做你的循环计数器等等),那么这是正确的。 如果它是一个真正 for
循环(说在Python或大多数函数式语言,你不能手动修改循环计数器),那么它是不正确的。
所有(可计算)功能,既可以递归和使用来实现while
环(或条件跳转,它们基本上是相同的)。 如果你真的限制自己for loops
,你只会得到的那些功能(原始递归的,如果你的基本操作是合理的)的一个子集。 诚然,这是一个非常大的子集,这恰好包含你可能在实践中encouter每一个功能。
什么是更重要的是,很多功能都是非常容易实现递归和非常难以实现迭代(手动管理您的调用堆栈不计)。
我似乎记得我的计算机科学教授说,早在一天,对具有递归解决所有的问题也有反复的解决方案。 他说,一个递归的解决方案通常是比较慢,但是当他们更容易推理和代码比迭代的解决方案,他们经常使用。
然而,在更先进的解决方案,递归的情况下,我不相信这将始终能够使用简单的实现他们for
循环。
是的, 说通过Thanakron Tandavas ,
递归是好当你要解决可以通过分而治之的技术来解决的问题。
例如:河内塔
很多很好的理由已经给出,我想与大家分享一个多点。 有些问题用递归精美解决,而只能通过递归来解决。 样品的例子是:
打印数组的所有值,但数组的项目可能是阵列为好。 有可能被嵌套数组作为好,但我们不能确定嵌套数组的深度。
一个美丽的解决办法是这样的:
<?php
function print_all_items($array){
foreach($array as $key=>$value){
if(is_array($value)) {
print_all_items($value);
}
else{
echo "$key => $value <br/>";
}
}
}
$array = array("first" => "first value",
"second" => "second value",
"third" => "third value",
"fourth"=>array(1,2,3,4,5),
"fifth"=>array(
"second array 1",
"second array 2",
"second array 3",
array(
"third array 1",
"third array 2",
"third array 3",
)
),
);
print_all_items($array);
输出:
first => first value
second => second value
third => third value
0 => 1
1 => 2
2 => 3
3 => 4
4 => 5
0 => second array 1
1 => second array 2
2 => second array 3
0 => third array 1
1 => third array 2
2 => third array 3
现在,这样的问题不能被解决的iterative approach
,因为问题的本质要求动态的解决方案。
递归+记忆可能会导致更有效的解决方案与纯迭代的方法比较,如检查: http://jsperf.com/fibonacci-memoized-vs-iterative-for-large-n
答案很简单:这种交易递归更快,对循环占用更少的内存在几乎所有情况。 但是通常有办法改变for循环或递归使其运行速度更快