尾递归讨论--待完结
2016-04-13 09:29
113 查看
按: 本文书于半年前,近日清理电脑内容,暂列于此。
尾递归优化
每一次递归调用都会在栈区引入新的一层方法栈。如递归求解fabonacci值。可写如下实现:
def fabonacci(n)
return n if n < 2
return fabonacci(n-1) + fabonacci(n-2)
end
这里调用一次fabonacci(n)将导致fabonacci(n-1)、fabonacci(n-2) 入栈。fabonacci(n-1)也会将fabonacci(n-2)、fabonacci(n-3)入栈。这样,递归次数将以指数增长
➜ expace ruby -rprofile fabonacci_tail.rb 1
% cumulative self self total
time seconds seconds calls ms/call ms/call name
0.00 0.00 0.00 2 0.00 0.00 Object#fab
0.00 0.00 0.00 1 0.00 0.00 Object#fab_recur
➜ expace ruby -rprofile fabonacci_tail.rb 2
% cumulative self self total
time seconds seconds calls ms/call ms/call name
0.00 0.00 0.00 3 0.00 0.00 Object#fab
0.00 0.00 0.00 3 0.00 0.00 Object#fab_recur
➜ expace ruby -rprofile fabonacci_tail.rb 4
% cumulative self self total
time seconds seconds calls ms/call ms/call name
0.00 0.00 0.00 5 0.00 0.00 Object#fab
0.00 0.00 0.00 9 0.00 0.00 Object#fab_recur
➜ expace ruby -rprofile fabonacci_tail.rb 8
% cumulative self self total
time seconds seconds calls ms/call ms/call name
0.00 0.00 0.00 9 0.00 0.00 Object#fab
0.00 0.00 0.00 67 0.00 0.00 Object#fab_recur
➜ expace ruby -rprofile fabonacci_tail.rb 16
% cumulative self self total
time seconds seconds calls ms/call ms/call name
87.50 0.07 0.07 3193 0.02 0.24 Object#fab_recur
0.00 0.08 0.00 17 0.00 0.00 Object#fab
➜ expace ruby -rprofile fabonacci_tail.rb 24 1 % cumulative self self total
time seconds seconds calls ms/call ms/call name
84.18 3.14 3.14 150049 0.02 0.41 Object#fab_recur
0.00 3.73 0.00 25 0.00 2.80 Object#fab
以上是求fabonacci(n)时的递归次数统计。 为什么没有fab(32),原因是fab(32)在本环境下profile要很长时间。故未列出。
由此可见,尾递归优化十分有效。
附 测试源代码
➜ expace cat fabonacci_tail.rb
def fab(n, a, b)
return a if n < 1
fab(n-1, b, a+b)
end
def fab_recur(n)
return n if n < 2
fab_recur(n-1) + fab_recur(n-2)
end
n=ARGV[0].to_i
fab(n,0,1)
fab_recur(n)
尝试使用了fact尾递归,似乎没有效果。
尾递归优化
每一次递归调用都会在栈区引入新的一层方法栈。如递归求解fabonacci值。可写如下实现:
def fabonacci(n)
return n if n < 2
return fabonacci(n-1) + fabonacci(n-2)
end
这里调用一次fabonacci(n)将导致fabonacci(n-1)、fabonacci(n-2) 入栈。fabonacci(n-1)也会将fabonacci(n-2)、fabonacci(n-3)入栈。这样,递归次数将以指数增长
➜ expace ruby -rprofile fabonacci_tail.rb 1
% cumulative self self total
time seconds seconds calls ms/call ms/call name
0.00 0.00 0.00 2 0.00 0.00 Object#fab
0.00 0.00 0.00 1 0.00 0.00 Object#fab_recur
➜ expace ruby -rprofile fabonacci_tail.rb 2
% cumulative self self total
time seconds seconds calls ms/call ms/call name
0.00 0.00 0.00 3 0.00 0.00 Object#fab
0.00 0.00 0.00 3 0.00 0.00 Object#fab_recur
➜ expace ruby -rprofile fabonacci_tail.rb 4
% cumulative self self total
time seconds seconds calls ms/call ms/call name
0.00 0.00 0.00 5 0.00 0.00 Object#fab
0.00 0.00 0.00 9 0.00 0.00 Object#fab_recur
➜ expace ruby -rprofile fabonacci_tail.rb 8
% cumulative self self total
time seconds seconds calls ms/call ms/call name
0.00 0.00 0.00 9 0.00 0.00 Object#fab
0.00 0.00 0.00 67 0.00 0.00 Object#fab_recur
➜ expace ruby -rprofile fabonacci_tail.rb 16
% cumulative self self total
time seconds seconds calls ms/call ms/call name
87.50 0.07 0.07 3193 0.02 0.24 Object#fab_recur
0.00 0.08 0.00 17 0.00 0.00 Object#fab
➜ expace ruby -rprofile fabonacci_tail.rb 24 1 % cumulative self self total
time seconds seconds calls ms/call ms/call name
84.18 3.14 3.14 150049 0.02 0.41 Object#fab_recur
0.00 3.73 0.00 25 0.00 2.80 Object#fab
以上是求fabonacci(n)时的递归次数统计。 为什么没有fab(32),原因是fab(32)在本环境下profile要很长时间。故未列出。
由此可见,尾递归优化十分有效。
附 测试源代码
➜ expace cat fabonacci_tail.rb
def fab(n, a, b)
return a if n < 1
fab(n-1, b, a+b)
end
def fab_recur(n)
return n if n < 2
fab_recur(n-1) + fab_recur(n-2)
end
n=ARGV[0].to_i
fab(n,0,1)
fab_recur(n)
尝试使用了fact尾递归,似乎没有效果。
相关文章推荐
- 如何修改app在模拟器上的名字
- 让文字实现在控件上的逐字显示(TextView为例)
- [windows]win7设置wifi热点
- kibana如何一打开页面就有数据图表
- mininet+pox+poxdesk使用入门
- iOS 基于 MVC 的项目重构总结
- WebView的碎片化解决方案:Crosswalk
- android项目大全,总有你所需的(二)
- 深入学习JVM笔记一JVM启动流程与基本结构
- nginx配置之location
- ios颜色设置的三种方式
- 使用Redis来实现LBS的应用
- 不仅能搜索还能查信息 带你了解LBS应用
- 定位技术GPS/A-GPS/LBS/WIFI定位介绍
- LBS推荐系统的设计方法
- 推荐系统的应用案例剖析
- [windows]窗口文件夹中使用常见任务
- C# 正则获取html内容
- iOS 8 Auto Layout界面自动布局系列4-使用VFL添加布局约束
- UITabBar部分自定义设置