递归函数最佳实践;这些是什么?
除了典型的递归函数之外,还有哪些其他独立于语言的设计递归函数的方法:
if (counter < 1)
return output;
else
callSelf();
是否存在其他方法?每当查看示例时,我总是会看到上面代码的一个版本。
谢谢! :)
What are some other language independent ways of designing recursive functions other than the typical:
if (counter < 1)
return output;
else
callSelf();
Do other methods even exist? Whenever viewing examples I always see a version of the code above.
Thanks! :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
差不多就这样了。
递归函数设计非常简单,就像“我可以返回一个值还是需要进行进一步处理?”和“处理返回了一个值,在传递它之前我该怎么做?”
尾递归只是编译器/解释器可以用来提高性能的一种优化方法。本质上,如果您的递归函数遵循严格的格式(递归调用后没有任何反应,通常意味着递归调用始终与
return
配对),则可以优化递归函数并将其重写为for循环。That's pretty much it.
Recursive function design is pretty much just as simple as "Can I return a value yet or do I need to do further processing?" and "Processing returned a value with it, what do I do to it before I pass it along?"
Tail-recursion is just an optimization method that a compiler/interpreter can use to increase performance. Essentially, if your recursive function follows a strict format (nothing happens after the recursive call, usually meaning the recursive call is always paired with the
return
) the recursive function can be optimized and rewritten as a for-loop.你的问题到底是什么?
只是尝试一些答案;-)
递归有多种类型:
“标准”递归
尾递归
互递归
定点递归< /p>
以及递归的应用列表极其富有。在函数式编程中,任何迭代代码(for 循环等)都是通过递归来表达的!
另一个很好的例子:
递归的主要“最佳实践”是确保在某个时刻满足终止条件,因此您通常会使用比初始调用“更小的”数据来自调用函数(只有一个)树的一部分)。其他一切都可能导致无休止的递归。
What exactly is your question?
Just trying some answers ;-)
There are many types of recursion:
"Standard" recursion
Tail recursion
Mutual recursion
Fixed-Point recursion
And the list of recursion's applications is extremely rich. In functional programming, any iterative code (for-loops etc.) is expressed through recursion!
Another good example:
The main "best-practice" of recursion is to make sure that your termination condition is satisfied at some point, so you'll typically self-call your function with "smaller" data than in the initial call (just one part of the tree). Everything else can result in endless recursions.
好吧,您需要有一些方法来知道何时停止递归。这就是你的计数器
1
是,对吗?我经常在列表中删除/添加项目、遍历树以及在递归时执行数学函数。最终,您需要知道何时停止递归,何时不停止,因此我没有看到任何其他选项不能归结为counter
counter < 1.
.Well, you need to have some method of knowing when to stop recursing. That's what your
counter < 1
is, correct? I frequently remove / add items to a list, traverse down trees, and perform mathematical functions while recursing. Ultimately, you need to know when to stop recursing and when not to, so I don't see any other options that can't be boiled down tocounter < 1
.在惰性编程语言中,您可以使用不定义终点的递归。结果可能是无限的数据结构,但只要您不尝试使用全部数据结构就可以。例如,在 Haskell 中定义整个斐波那契数列的常见方法是这样的:
这翻译成以下英语:斐波那契数列是 1,后面跟着 1,后面跟着的数列是斐波那契数列的元素之和,没有第一个元素的斐波那契数列。
这听起来像是一个递归定义,而不是递归函数调用,但在 Haskell 中没有太大区别 - 上面只是一个“空函数”(不带参数的函数)。
通常要使用它,您只需使用 fibS 的前 N 个元素。事实上,您可以使用所有这些(例如全部打印),只要您对程序永远运行感到满意:-)
对于使用无限递归的“全部”的更有用的示例,Web 服务器可能有一个使用不会终止的递归函数定义的永远运行的“主循环”。
编辑:如果存在某些“惰性”元素,这些原则当然可以应用于其他语言。以下是使用生成器将 fibS 移植到 Python 的上述实现:
不要指望它与 Haskell 版本一样高效!您可以使用一些技巧和某种全局对象来提高它的效率。但请注意缺乏明确的终止条件。
In lazy programming languages, you can have recursion that doesn't define an end point. The result could be an infinite data structure, but that's OK as long as you don't try to use all of it. For example, a common way to define the entire fibonacci series in Haskell is this:
This translates into the following English: the Fibonacci series is 1, followed by 1, followed by the series which is the element-wise sum of the Fibonacci series and the Fibonacci series without its first element.
This sounds like a recursive definition, rather than recursive function calling, but in Haskell there is no big distinction - the above is just a 'nullary function' (one that takes no arguments).
Normally to use this, you would just use the first N elements of fibS. You can in fact use all of it (e.g. print it all), as long as you are happy with your program running forever :-)
For a more useful example of using 'all' of an infinite recursion, a web server might have a 'main loop' that runs forever defined using a recursive function that does not terminate.
EDIT: These principles can certainly be applied to other languages if some element of 'laziness' is present. Here is the above implementation of fibS ported to Python using generators:
Don't expect it to be as efficient as the Haskell version! You could make it more efficient using some hacks and global objects of some kind. But notice the lack of explicit termination conditions.
有很多变体,例如:
或
它们的共同点是,它们将任务分成更小的任务,然后使用自身来解决更小的任务,直到它们小到可以通过简单的操作来解决。
There are a lot of variations, for example:
or
What they all have in common is that they devide the task into smaller tasks and then uses itself to solve the smaller tasks until they are so small that they can be solved with a trivial operation.
如果您希望停止递归,则必须进行测试。
但你可以有一些不同的东西,比如河内塔算法(2个递归调用):
将打印将 8 个圆盘从源移动到目的地的解决方案。请参阅 http://en.wikipedia.org/wiki/Tower_of_Hanoi 了解游戏规则。
If you want your recursion to stop, you have to put a test.
But you can have things which vary a bit, like the Hanoi Tower algorithm (2 recursive call):
Will print the solution of moving 8 discs from source to dest. See http://en.wikipedia.org/wiki/Tower_of_Hanoi for the rules of the game.
Google 提供了大量有关递归的信息。 :)
Google has a lot of information on recursion. :)
“最佳实践”是尝试使用结构归纳法(粗略地说,是数据结构的折叠)。如果失败,您可能需要考虑一般(无限制)递归。
例如,在处理列表时,通常使用折叠。许多函数,例如串联和附加,很容易用这种方式描述。
The "best practice" is to try to use structural induction (roughly, a fold over the datastructure). If that fails, you might want to consider general (unrestricted) recursion.
For example, when working with lists, it is customary to use a fold. Many functions, such as concatenation and append are easy to describe in this fashion.