- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我想知道递归是否是解决问题的唯一方法,那么堆栈迭代是唯一的其他解决方法吗?我认为它们是等价的:如果递归有效,那么迭代肯定有效,反之亦然。
此外,我不确定为什么递归被认为是低效的并且经常导致堆栈溢出,而使用堆栈的迭代则不会。递归只是以用户不可见的自动方式使用堆栈。
最佳答案
虽然dancancode的 answer谈论不同类型的问题,例如 primitive recursive问题,recursive问题和recursively enumerable问题,恕我直言,这个问题更直接recursion或 iteration .
I wonder if recursion is the only solution to a problem, then is iteration with stacks the only other solution?
不,有很多不同的计算模型。然而,lambda calculus (递归的基础)和Turing machines (迭代的基础)是最流行的计算模型。另一个流行的计算模型是 μ-recursion .
什么是计算模型?
很长一段时间以来,数学家们都想研究计算的本质。他们想知道哪些问题可以计算(即哪些问题有解),哪些问题不能计算(即哪些问题无解)。他们还想知道计算的性质(例如,计算相对于输入大小的解决方案需要多少时间等)。
但是,只有一个问题:“计算”是一个非常抽象的术语。你如何推理一些不具体的事情?这就是数学家需要一个他们可以推理的计算模型的原因。计算模型捕获了“计算的本质”。这意味着如果存在可以计算的问题,那么在每个计算模型中都必须有一种算法来计算它。
I think they're kind of equivalent: If recursion works, then iteration will work for sure, and vice versa.
是的,没错。 Church-Turing thesis从本质上讲,每个计算模型在功率上都是等效的。因此,您可以使用递归(即 lambda 演算)完成的所有事情也可以使用迭代(即图灵机)完成。
事实上,世界上大多数计算机都是基于图灵机的。因此,每台计算机都只使用迭代。尽管如此,您的计算机仍然可以执行递归程序。这是因为编译器将您的递归程序翻译成迭代机器代码。
Also, I'm not sure why recursion is considered inefficient and often causes stack overflows while iteration with stacks does not. Recursion just uses stacks in an automatic way invisible to the user.
这是因为操作系统处理进程的方式。大多数操作系统都对堆栈的大小施加了最大限制。在我的 Linux 操作系统上,最大堆栈大小为 8192 KB,这不是很多。使用 ulimit -s
查找 POSIX 兼容操作系统上的默认堆栈大小。这就是使用太多递归导致堆栈溢出的原因。
另一方面,堆的大小可以在进程执行时动态增加(只要有可用空间)。因此,您不必担心在使用迭代时内存不足(即使在使用显式堆栈时)。
此外,递归通常比迭代慢,因为调用函数需要 context switch而在迭代中你只需要修改指令指针(即跳转,可能是有条件的)。
然而,这并不意味着迭代总是优于递归。递归程序通常比迭代程序更小且更容易理解。此外,在某些情况下,编译器可以通过 tail call optimization 完全消除上下文切换。 (总拥有成本)。这不仅使递归与迭代一样快,而且确保堆栈大小不会增加。
有趣的是,所有的递归程序都可以通过将程序翻译成continuation-passing style 来实现尾递归。 (CPS)。因此,CPS 和 TCO 可以 eliminate the need of an implicit call stack共。一些函数式编程语言的编译器和解释器在 novel ways 中使用了这种能力.
关于algorithm - 递归与堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35097729/
在本教程中,您将借助示例了解 JavaScript 中的递归。 递归是一个调用自身的过程。调用自身的函数称为递归函数。 递归函数的语法是: function recurse() {
我的类(class) MyClass 中有这段代码: public new MyClass this[int index] { get {
我目前有一个非常大的网站,大小约为 5GB,包含 60,000 个文件。当前主机在帮助我将站点转移到新主机方面并没有做太多事情,我想的是在我的新主机上制作一个简单的脚本以 FTP 到旧主机并下载整个
以下是我对 AP 计算机科学问题的改编。书上说应该打印00100123我认为它应该打印 0010012但下面的代码实际上打印了 3132123 这是怎么回事?而且它似乎没有任何停止条件?! publi
fun fact(x: Int): Int{ tailrec fun factTail(y: Int, z: Int): Int{ if (y == 0) return z
我正在尝试用c语言递归地创建线性链表,但继续坚持下去,代码无法正常工作,并出现错误“链接器工具错误 LNK2019”。可悲的是我不明白发生了什么事。这是我的代码。 感谢您提前提供的大力帮助。 #inc
我正在练习递归。从概念上讲,我理解这应该如何工作(见下文),但我的代码不起作用。 请告诉我我做错了什么。并请解释您的代码的每个步骤及其工作原理。清晰的解释比只给我有效的代码要好十倍。 /* b
我有一个 ajax 调用,我想在完成解析并将结果动画化到页面中后调用它。这就是我陷入困境的地方。 我能记忆起这个功能,但它似乎没有考虑到动画的延迟。即控制台不断以疯狂的速度输出值。 我认为 setIn
有人愿意用通俗易懂的语言逐步解释这个程序(取自书籍教程)以帮助我理解递归吗? var reverseArray = function(x,indx,str) { return indx == 0 ?
目标是找出数组中整数的任意组合是否等于数组中的最大整数。 function ArrayAdditionI(arr) { arr.sort(function(a,b){ return a -
我在尝试获取 SQL 查询所需的所有数据时遇到一些重大问题。我对查询还很陌生,所以我会尽力尽可能地描述这一点。 我正在尝试使用 Wordpress 插件 NextGen Gallery 进行交叉查询。
虽然网上有很多关于递归的信息,但我还没有找到任何可以应用于我的问题的信息。我对编程还是很陌生,所以如果我的问题很微不足道,请原谅。 感谢您的帮助:) 这就是我想要的结果: listVariations
我一整天都在为以下问题而苦苦挣扎。我一开始就有问题。我不知道如何使用递归来解决这个特定问题。我将非常感谢您的帮助,因为我的期末考试还有几天。干杯 假设有一个包含“n”个元素的整数数组“a”。编写递归函
我有这个问题我想创建一个递归函数来计算所有可能的数字 (k>0),加上数字 1 或 2。数字 2 的示例我有两个可能性。 2 = 1+1 和 2 = 2 ,对于数字 3 两个 poss。 3 = 1+
目录 递归的基础 递归的底层实现(不是重点) 递归的应用场景 编程中 两种解决问题的思维 自下而上(Bottom-Up) 自上而下(Top-
0. 学习目标 递归函数是直接调用自己或通过一系列语句间接调用自己的函数。递归在程序设计有着举足轻重的作用,在很多情况下,借助递归可以优雅的解决问题。本节主要介绍递归的基本概念以及如何构建递归程序。
我有一个问题一直困扰着我,希望有人能提供帮助。我认为它可能必须通过递归和/或排列来解决,但我不是一个足够好的 (PHP) 程序员。 $map[] = array("0", "1", "2", "3")
我有数据 library(dplyr, warn.conflicts = FALSE) mtcars %>% as_tibble() %>% select(mpg, qsec) %>% h
在 q 中,over 的常见插图运算符(operator) /是 implementation of fibonacci sequence 10 {x,sum -2#x}/ 1 1 这确实打印了前 1
我试图理解以下代码片段中的递归调用。 static long fib(int n) { return n <= 1 ? n : fib(n-1) + fib(n-2); } 哪个函数调用首先被
我是一名优秀的程序员,十分优秀!