Programming Clojure学习笔记——函数编程
来源:互联网 发布:it服务 编辑:程序博客网 时间:2024/06/06 01:15
5.4 再谈递归
相互递归:两个或两个以上函数之间互相调用。如:
(declare my-odd? my-even?)
(defn my-odd? [n]
(if (= n 0)
false
(my-even? (dec n))))
(defn my-even? [n]
(if (= n 0)
true
(my-odd? (dec n))))
有四种方法解决这种互相调用递归计算问题:
(1) 转换为自递归,即函数自己调用自己
找出各个函数之间的共性,定义一个公共的递归函数,被各个函数调用得到各自返回值
(2) 利用Clojure的trampoline函数执行递归计算
(trampoline f & partial-args)
如果返回值不是函数,则直接像调用函数一样执行,如
(trampoline + 1 2) # 返回 3
如果返回值是函数,则递归调用函数直到返回值不是函数为止。
说明:对于相互调用的递归函数内部调用其他函数的语句前需要加#号,标识为匿名函数。
如上面的函数修改为:
(declare my-odd? my-even?)
(defn my-odd? [n]
(if (= n 0)
false
#(my-even? (dec n))))
(defn my-even? [n]
(if (= n 0)
true
#(my-odd? (dec n))))
通过trampoline函数计算值:
user=> (trampoline my-even? 1000000)
true
(3) 使用延迟替换递归
(4) 通过缓存加快递归
解决如下问题:
F(0) = 1; M(0) =0;
F(n) = n - M(F(n-1)), n > 0
M(n) = n - F(M(n-1)), n > 0
计算M(10000)
定义函数:
(declare m f)
(defn m [n]
(if (zero? n) 0 (- n (f (m (dec n))))))
(defn f [n]
(if (zero? n) 1 (- n (m (f (dec n))))))
直接计算M(10000)会出现堆栈溢出
利用Clojure的memorize函数,将m和f函数变成带缓存版本:
(def m (memoize m))
(def f (memoize f))
此时直接计算M(10000)也会出现堆栈溢出
以序列代替函数:
(def m-seq (map m (iterate inc 0)))
(def f-seq (map f (iterate inc 0)))
此时计算M(10000),即取序列m-seq的第10000个元素:
(nth m-seq 10000) 返回 6180
相互递归:两个或两个以上函数之间互相调用。如:
(declare my-odd? my-even?)
(defn my-odd? [n]
(if (= n 0)
false
(my-even? (dec n))))
(defn my-even? [n]
(if (= n 0)
true
(my-odd? (dec n))))
有四种方法解决这种互相调用递归计算问题:
(1) 转换为自递归,即函数自己调用自己
找出各个函数之间的共性,定义一个公共的递归函数,被各个函数调用得到各自返回值
(2) 利用Clojure的trampoline函数执行递归计算
(trampoline f & partial-args)
如果返回值不是函数,则直接像调用函数一样执行,如
(trampoline + 1 2) # 返回 3
如果返回值是函数,则递归调用函数直到返回值不是函数为止。
说明:对于相互调用的递归函数内部调用其他函数的语句前需要加#号,标识为匿名函数。
如上面的函数修改为:
(declare my-odd? my-even?)
(defn my-odd? [n]
(if (= n 0)
false
#(my-even? (dec n))))
(defn my-even? [n]
(if (= n 0)
true
#(my-odd? (dec n))))
通过trampoline函数计算值:
user=> (trampoline my-even? 1000000)
true
(3) 使用延迟替换递归
(4) 通过缓存加快递归
解决如下问题:
F(0) = 1; M(0) =0;
F(n) = n - M(F(n-1)), n > 0
M(n) = n - F(M(n-1)), n > 0
计算M(10000)
定义函数:
(declare m f)
(defn m [n]
(if (zero? n) 0 (- n (f (m (dec n))))))
(defn f [n]
(if (zero? n) 1 (- n (m (f (dec n))))))
直接计算M(10000)会出现堆栈溢出
利用Clojure的memorize函数,将m和f函数变成带缓存版本:
(def m (memoize m))
(def f (memoize f))
此时直接计算M(10000)也会出现堆栈溢出
以序列代替函数:
(def m-seq (map m (iterate inc 0)))
(def f-seq (map f (iterate inc 0)))
此时计算M(10000),即取序列m-seq的第10000个元素:
(nth m-seq 10000) 返回 6180
- Programming Clojure学习笔记——函数编程
- Programming Clojure学习笔记——函数编程
- Programming Clojure学习笔记——函数编程
- Programming Clojure学习笔记——函数编程
- Programming Clojure笔记之四——函数式编程
- Programming Clojure学习笔记——探索Clojure
- Programming Clojure学习笔记——探索Clojure
- Programming Clojure学习笔记——探索Clojure
- Programming Clojure学习笔记——探索Clojure
- Programming Clojure学习笔记——探索Clojure
- Programming Clojure学习笔记——探索Clojure
- Programming Clojure学习笔记——前言
- Programming Clojure学习笔记——开始
- Programming Clojure学习笔记——开始
- Programming Clojure学习笔记——开始
- Programming Clojure学习笔记——并发
- Programming Clojure学习笔记——并发
- Programming Clojure学习笔记——并发
- 人体感知与线性系统
- Programming Clojure学习笔记——函数编程
- Programming Clojure学习笔记——函数编程
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- Programming Clojure学习笔记——函数编程
- Programming Clojure学习笔记——函数编程
- 视图之UiView和UiWindow
- poj 1422 Air Raid 最小二分匹配 基础
- Windows程序设计__孙鑫C++Lesson18《ActiveX 控件》
- GNOME 3 介绍 技巧
- js如何禁用鼠标右键
- How floating point numbers are represented
- 一个简单实用的SSAO实现
- 一个穆斯林乡佬的清洁世界