chapter_computational_complexity/iteration_and_recursion/ #694
Replies: 116 comments 155 replies
-
我算法小白理解的递归和尾递归,递归就好像是拿着个小本本,算一次,算不出答案,需要标记一下继续算,一直到最后一个答案算出来再根据标记往回总结答案,而尾递归则是算一次更新一下答案,所以到最后答案可以直接得出,这样的话感觉跟迭代很像啊 |
Beta Was this translation helpful? Give feedback.
-
简单查了一下好像支持尾递归优化的语言不多,相对主流一些的语言 Java、Python、Go 之类的都不支持。 |
Beta Was this translation helpful? Give feedback.
-
f(n),f是什么意思 |
Beta Was this translation helpful? Give feedback.
-
希望添加迭代器的代码 |
Beta Was this translation helpful? Give feedback.
-
我愿称之为最强教程。这一章终于完全理解了迭代和递归的不同,终于完全理解了尾递归。豁然开朗的爽感让我继续如饥似渴地阅读下面的内容! |
Beta Was this translation helpful? Give feedback.
-
很多语言没有对尾递归进行优化,数据量不确定的情况下,用递归风险岂不是很大 |
Beta Was this translation helpful? Give feedback.
-
开头第一段话因为我不是很懂,所以去问了一下GPT,回复说:“迭代和递归都是程序中常见的控制结构,而不是程序结构本身。”这个回答是正确的吗?以及控制结构和程序结构的同异是什么呢?🤔 |
Beta Was this translation helpful? Give feedback.
-
比作挖坑的话 然后迭代解题关键就是计算好每次挖多少,迭代每次挖的土都是固定的重量,最后只管算挖了几次就能知道。 迭代跟递归配合就是 在原地挖坑?不用往前走也不用去下一层 直接原地计算?有点迷糊了。 int fibonacci(int n) {
if (n <= 0) {
return 0;
}
if (n == 1) {
return 1;
}
int prev = 0; // 第一个斐波那契数
int current = 1; // 第二个斐波那契数
int result = 0; // 存储计算的结果
for (int i = 2; i <= n; ++i) {
result = prev + current;
prev = current;
current = result;
}
return result;
} chatgpt的迭代加递归 原地搞三个坑prev current result |
Beta Was this translation helpful? Give feedback.
-
例如在以下代码中,条件变量,每轮进行了两次更新,这种情况就不太方便用 for 循环实现。 /* while 循环(两次更新) */
int whileLoopII(int n) {
int res = 0;
int i = 1; // 初始化条件变量
// 循环求和 1, 4, ...
while (i <= n) {
res += i;
// 更新条件变量
i++;
i *= 2;
}
return res;
} 这个地方提到用for循环不好实现,可是 int res = 0;
for (int i1 = 1; i1 <= n; ) {
res += i1;
i1++;
i1 *= 2;
} 这样写也一样能实现的,感觉和while没啥大的区别 |
Beta Was this translation helpful? Give feedback.
-
分治是一种算法设计思想,它通过将问题划分为多个相同或相似子问题,并分别解决这些子问题,最后将子问题的解合并起来得到原始问题的解。分治思想通常包括三个步骤:分解、解决和合并。
分治思想通常用于解决问题的规模较大、复杂度较高的情况,它可以将原问题划分为多个较小的子问题,从而简化原问题的求解过程。常见的应用包括归并排序、快速排序、二分搜索等。通过分治思想,可以提高算法的效率和可扩展性。分治是一种算法设计思想,它通过将问题划分为多个相同或相似子问题,并分别解决这些子问题,最后将子问题的解合并起来得到原始问题的解。分治思想通常包括三个步骤:分解、解决和合并。
分治思想通常用于解决问题的规模较大、复杂度较高的情况,它可以将原问题划分为多个较小的子问题,从而简化原问题的求解过程。常见的应用包括归并排序、快速排序、二分搜索等。通过分治思想,可以提高算法的效率和可扩展性。 |
Beta Was this translation helpful? Give feedback.
-
”普通递归:当函数返回到上一层级的函数后,需要继续执行代码,因此系统需要保存上一层调用的上下文。” |
Beta Was this translation helpful? Give feedback.
-
C#的命名有点不友好, |
Beta Was this translation helpful? Give feedback.
-
问在for循环中什么c++里面是++i,c中就是i++ |
Beta Was this translation helpful? Give feedback.
-
请问,我用 print(fib(4)); 运行得到的结果是2,这和理解上的不一致,在本本上演算也是2,请问是哪里做的不对吗? |
Beta Was this translation helpful? Give feedback.
-
请问为什么我的VScode控制台运行结果乱码?如何解决呢?谢谢大佬
|
Beta Was this translation helpful? Give feedback.
-
听懂了!很nice import matplotlib.pyplot as plt
def for_loop_recur(n:int) -> int:
# 使用迭代模拟递归
stack = []
res = 0
accumulation_values = []# 记录每次累加值
for i in range(n,0,-1):
stack.append(i) # 此时传入的同时栈的长度被n规定
while stack:
# 使用res累加,pop推出栈底获取累加结果
res += stack.pop()
accumulation_values.append(res)
return res, accumulation_values
n = 100
out, accumulation_values = for_loop_recur(n)
print(f"最终累加结果为:{out}")
#for i in range(1,n,5):
# print(accumulation_values[i])
x = list(range(1, len(accumulation_values) + 1))
# 绘制折线图
plt.plot(x, accumulation_values, marker='o')
# 设置图表标题和坐标轴标签
plt.title('Data Over Time')
plt.xlabel('Time (Index)')
plt.ylabel(accumulation_values)
# 显示网格
plt.grid(True)
# 显示图表
plt.show() |
Beta Was this translation helpful? Give feedback.
-
/* 双层 for 循环 */
char *nestedForLoop(int n) {
// n * n 为对应点数量,"(i, j), " 对应字符串长最大为 6+10*2,加上最后一个空字符 \0 的额外空间
int size = n * n * 26 + 1;
char *res = malloc(size * sizeof(char));
// 循环 i = 1, 2, ..., n-1, n
for (int i = 1; i <= n; i++) {
// 循环 j = 1, 2, ..., n-1, n
for (int j = 1; j <= n; j++) {
char tmp[26];
snprintf(tmp, sizeof(tmp), "(%d, %d), ", i, j);
strncat(res, tmp, size - strlen(res) - 1);
}
}
return res;
} 这个双重循环代码,我认为在snprintf这个函数这里有点问题,snprintf函数第二个参数size,是当字符串 |
Beta Was this translation helpful? Give feedback.
-
关于斐波那契数列的例子里有多少层的问题,可以看CS61A讲义里的图解,更准确,这个递归树并不是严格对称的,因为第0,1,2个数字并不遵循后面的递进规律,但是递归的逻辑是一样的,需要层层递进。https://cs61a.org/disc/disc04/disc04.pdf |
Beta Was this translation helpful? Give feedback.
-
你好,我觉得新手(我)从“递归”往“尾递归”转换有点难度,需要一些时间去思考 |
Beta Was this translation helpful? Give feedback.
-
關於 递归 调用栈的描述疑問: 1.函数的上下文数据都存储在称为“栈帧空间”的内存区域中,直至函数返回后才会被释放。因此,递归通常比迭代"更加耗费内存空间"。 為什麼最後的結論是时间效率更低,而不是繼承前一點脈絡為空間效率更低 |
Beta Was this translation helpful? Give feedback.
-
我的可视化运行程序怎么是空的,没有展示 |
Beta Was this translation helpful? Give feedback.
-
我学海八舍潘红臣实名签到 |
Beta Was this translation helpful? Give feedback.
-
试了一下用尾递归来解决斐波那契数列 |
Beta Was this translation helpful? Give feedback.
-
从这节开始明显变难了,想要理解得下功夫。我一年前被递归搞得遍体鳞伤,没想到一年后还是不咋样😂 |
Beta Was this translation helpful? Give feedback.
-
分享一下【递归】这块我的学习心得,之前也在别的书上看过,看的时时候感觉懂了,事后不是忘了就是遇到具体问题时不会用,说明没有掌握其精髓,这里我已文中最开始的示例举另一种例子帮助新手理解,作者文中给的是1到5的等差数列相加,例子使用了一个recur(5)的函数来演示,该函数只有一个参数,设计的很巧妙,但新手可能不太好理解这种巧妙。这里我降低难度换另一种思路帮新手理解:要计算1到5的等差数列之和,我们很容易受到题目要求的影响,潜意识认为应该设计一个函数recur(a,b),并在实际调用时使用recur(1,5)的方式去调用,这种思路当然可以,我们就按这个思路去设计。递归讲究的是把复杂问题分解为简单问题来解决,所以我们要先利用这个思想,1+2+3+4+5我可能不会算,但1+2我会,2+3我会,3+4我也会,总之就是我会最简单的2个数相加,那就好办了,我们把1+2+3+4+5尽可能的简化为2个数相加的模式,然后我们通过观察会发现开始的第一步一定是1+2,最后一步是4+5,当然也可以反过来倒着算5+4+3+2+1,不论正算反算,最后都是2个数相加,并且两个数之间相差1(例如1+2种的1和2,以及4+5中的4和5),这样我们现在知道的中止递归的条件,那就是当两个数相减相差1的时候就是“递转归”的时机。于是有以下代码,该代码不仅可以计算1到5的等差数列之和,也可以计算其他类型等差数列之和,比如2到6,具体代码如下: def recur(a, b):
if b - a == 1:
return a + b
res = recur(a + 1, b)
return res + a
c = recur(1, 5)
print(c) 最后我想对新手说的是,要想真正自己掌握递归,出了要记作者文中住递归用法的三个要素,更要自己动手去解一些递归小题目,不要一上来看答案,先尝试自己设计一下,会更容易让你理解递归! |
Beta Was this translation helpful? Give feedback.
-
谢谢您的邮件。我会尽快回复您!
|
Beta Was this translation helpful? Give feedback.
-
def fib(n:int)->int: print(fib(5)) number is 1 |
Beta Was this translation helpful? Give feedback.
-
chapter_computational_complexity/iteration_and_recursion/
动画图解、一键运行的数据结构与算法教程
https://www.hello-algo.com/chapter_computational_complexity/iteration_and_recursion/
Beta Was this translation helpful? Give feedback.
All reactions