ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: 彭希仁

递归(基础教程)

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2015-3-17 16:44 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖已被收录到知识树中,索引项:递归
下标越界 发表于 2015-3-17 14:31
n=30时,调用函数的次数是1664079次。n=1,2,3……30的次数总和是4356586次。

呵呵,逻辑上正确的递归代码应该是:

If n > 1 Then Fib = Fib(n - 1) + Fib(n - 2) Else If n Then Fib = 1

因此n=30时,需调用递归过程 2692537次。

而我一开始给出的递归代码是:
If n > 2 Then Fib = Fib(n - 1) + Fib(n - 2) Else If n Then Fib = 1

这个在算法逻辑上讲是有问题的,但从实际效果上来看却仍然是正确的……误打误撞而已。
因为 n=2时,碰巧结果=1 所以没有导致错误而已。

但这么用的话,显然可以节省很多次的递归过程了。
所以,最后结果递归次数只有=1664079次了。

…………
其实,我前面的回帖已经更正为 n > 1 。

TA的精华主题

TA的得分主题

发表于 2015-3-18 11:41 | 显示全部楼层
香川群子 发表于 2015-3-17 16:44
呵呵,逻辑上正确的递归代码应该是:

If n > 1 Then Fib = Fib(n - 1) + Fib(n - 2) Else If n Then F ...

    群子说得很对。群子的代码n=30时,调用次数确实是2692537次。
    倒是我对顺序语句及静态变量static的在顺序语句中使用位置没有仔细考虑,笼统地认为只要放在Fibo函数中就OK了。现在看来其实不然。
    以下是我的测试代码:
  1. Function Fibo(n%, arr) '香川群子版 斐波那契数 递归计算
  2.   Static a&
  3.    
  4.    

  5.     If n > 1 Then Fibo = Fibo(n - 1, arr) + Fibo(n - 2, arr) Else If n Then Fibo = 1
  6.    
  7.     a = a + 1
  8.     arr(n) = a
  9.    
  10. End Function
  11. Sub 测试香川版斐波拉契数递归计算()
  12. Dim i%, r, c, tim1, tim2, nrec(), nCount(), n%
  13. Static nStart&
  14. n = 30

  15. ReDim nrec(n), nCount(n)




  16. Rows.Clear

  17. i = 1

  18. tim1 = Timer
  19. Do While i <= 30
  20. Cells(Int((i - 1) / 10) + 3, (i - 1) Mod 10 + 1) = Fibo(i, nrec)
  21. nrec(i) = nrec(i) - nStart

  22. Cells(Int((i - 1) / 10) + 11, (i - 1) Mod 10 + 1) = nrec(i)


  23. nCount(i) = nrec(i)
  24. Cells(Int((i - 1) / 10) + 19, (i - 1) Mod 10 + 1) = nCount(i) - nCount(i - 1)
  25. i = i + 1
  26. Loop
  27. tim2 = Timer

  28. nStart = nStart + nrec(n)
  29. MsgBox nStart
  30. Cells(1, 1) = tim2 - tim1
  31. Range("A2") = "F(1)、F(2)、……、F(30)"
  32. Range("A10") = "计算F(1)、F(2)、……、F(30)调用递归函数次数总和"
  33. Range("A18") = "计算F(n)调用递归函数次数"


  34. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2015-3-18 14:06 | 显示全部楼层
群子可能以为我使用静态变量做计数器对
If n > 2 Then Fibo = Fibo(n - 1, arr) + Fibo(n - 2, arr) Else If n Then Fibo = 1
作了n=30的调用次数测试(正巧群子在编辑回帖时曾首发语句是该句),所以才测试出n=30时,调用次数是1664079次。

其实我看到的是群子已经修改后的这句:
If n > 1 Then Fibo = Fibo(n - 1, arr) + Fibo(n - 2, arr) Else If n Then Fibo = 1
但在加入静态变量计数器时,语句位置放在该句的前面,即:
Static a&

    a = a + 1
    arr(n) = a

  If n > 1 Then Fibo = Fibo(n - 1, arr) + Fibo(n - 2, arr) Else If n Then Fibo = 1

于是得出了群子的Fibo函数在n=30时,调用次数仍然是1664079次的错误结果。

现在看来要正确的计次数,静态变量及赋值应该放在 If n > 1 Then Fibo = Fibo(n - 1, arr) + Fibo(n - 2, arr) Else If n Then Fibo = 1后面,即如上面贴出的代码顺序。

   

TA的精华主题

TA的得分主题

发表于 2015-12-18 15:03 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2016-3-8 11:26 | 显示全部楼层
Long_III 发表于 2007-1-26 10:06
QUOTE:以下是引用彭希仁在2007-1-25 11:17:16的发言:对于数字一来说,也只有0(不出现)和1(出现) 两种 ...

请教版主,如果20个数,不用i=1 to 20 而用 i = 1 to 2怎么用法,不理解?

TA的精华主题

TA的得分主题

发表于 2016-7-7 09:10 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-1-21 11:11 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-1-21 20:14 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-2-28 21:35 | 显示全部楼层
dcw0402 发表于 2010-3-15 19:02
彭版38楼这个迷宫我做了好几天了,也没结果,能否给个答案,头已太大了,救命

[ 本帖最后由 dcw0402 于 2010 ...

老师,请问这个迷宫您解答出来了吗?

TA的精华主题

TA的得分主题

发表于 2018-8-28 21:13 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-22 11:31 , Processed in 0.042147 second(s), 7 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表