舉例分析迭代及遞歸的復(fù)雜度(scheme代碼實現(xiàn))

分別用遞歸和迭代的方式實現(xiàn)下述的公式:


分子部分的規(guī)律為:從第二個開始腹鹉,每兩個數(shù)遞增一次枷畏。因此瓮增,可以用如下公式表示:
其中div(n,2)表示n整除2得到的結(jié)果怎棱。
用程序計算分子中第n個數(shù)的值,如下所示:

(define (numerator-num n)
  (* (+ (quotient n 2)
        1)
     2))

分母部分的規(guī)律為:從第一個開始绷跑,每兩個數(shù)遞增一次拳恋。因此,可以用如下公式表示:


用程序計算分母中第n個值砸捏,如下所示:

(define (denominator-num n)
  (+ (* (quotient (+ n 1) 2)
     2)
     1))

對于類似

既可以用遞歸谬运,也可以用迭代的形式得到。
(1)遞歸表示

(define (product term a next b)
  (if (> a b)
      1
      (* (term a)
         (product term (next a) next b))))

代碼中product是過程名垦藏,term是公式中的函數(shù)f梆暖,a是起始計算值(也就是公式中的a1),b的終止運算值(也就是公式中的an)掂骏。next指的是a(k)變化到a(k+1)的規(guī)律轰驳,比如對于公式中的分子分母而言,a(k)=k弟灼,a(k+1)=k+1级解,因此這里的next就是進行加一操作。遞歸的思想是通過反復(fù)調(diào)用過程product田绑,得到最終的結(jié)果:


用程序表示過程勤哗,可以表示為:

(2)迭代表示

(define (product term a next b)
  (define (iter a result)
    (if (> a b)
        result
        (iter (next a) (* (term a) result))))
  (iter a 1))

迭代與遞歸最根本的區(qū)別在于:遞歸會不停地展開,直到完全展開辛馆,然后開始代入計算俺陋;迭代會不停的對數(shù)據(jù)進行替代,而不會展開數(shù)據(jù)昙篙。比如該段代碼的公式表示為:![][7]
result值會在迭代過程中不斷更新腊状,直到最后將result輸出。

其實有兩種實現(xiàn)方式苔可,一種是分別迭代或遞歸分子和分母缴挖,最后將分子和分母相除;另一種是講對應(yīng)項的分子和分母看作整體焚辅,再進行迭代或遞歸映屋。

因此,可以得到2中不同的遞歸和迭代方式同蜻。
(1)遞歸方式1:分子分母分別遞歸棚点,最后再相除。

#lang planet neil/sicp
(#%require (only racket/base current-inexact-milliseconds))


(define (fraction n)
  (define start-time (current-inexact-milliseconds))
  (/ (numerator n)
     (denominator n))
  (newline)
  (define end-time (current-inexact-milliseconds))
  (display (- end-time start-time)))

(define (numerator n)
  (define (fractions-next x) (+ x 1))
  (product numerator-num 1 fractions-next n))

(define (denominator n)
  (define (fractions-next x) (+ x 1))
  (product denominator-num 1 fractions-next n))

(define (numerator-num n)
  (* (+ (quotient n 2)
        1)
     2))

(define (denominator-num n)
  (+ (* (quotient (+ n 1) 2)
     2)
     1))

(define (product term a next b)
  (if (> a b)
      1
      (* (term a)
         (product term (next a) next b))))

(2)遞歸方式2:分子分母看作一個整體湾蔓,再進行遞歸瘫析。

#lang planet neil/sicp
(#%require (only racket/math pi))
(#%require (only racket/base current-inexact-milliseconds))


(define (fraction n)
  (define start-time (current-inexact-milliseconds))
  (define (fractions-next x) (+ x 1))
  (product fraction-num 1 fractions-next n)
  (define end-time (current-inexact-milliseconds))
  (display (- end-time start-time)))


(define (fraction-num n)
  (/ (numerator_num n)
     (denominator_num n)))


(define (numerator_num n)
  (* (+ (quotient n 2)
        1)
     2))

(define (denominator_num n)
  (+ (* (quotient (+ n 1) 2)
     2)
     1))


(define (product term a next b)
  (if (> a b)
      1
      (* (term a)
         (product term (next a) next b))))

(3)迭代方式1:分子分母分別迭代,最后再相除。

#lang planet neil/sicp
(#%require (only racket/base current-inexact-milliseconds))

(define (fraction n)
  (define start-time (current-inexact-milliseconds))
  (/ (numerator n) (denominator n))
  (newline)
  (define end-time (current-inexact-milliseconds))
  (display (- end-time start-time)))

(define (numerator n)
  (define start-time (current-inexact-milliseconds))
  (define (fractions-next x) (+ x 1))
  (product numerator_num 1 fractions-next n))

(define (denominator n)
  (define (fractions-next x) (+ x 1))
  (product denominator_num 1 fractions-next n))

(define (numerator_num n)
  (* (+ (quotient n 2)
        1)
     2))

(define (denominator_num n)
  (+ (* (quotient (+ n 1) 2)
     2)
     1))

(define (product term a next b)
  (define (iter a result)
    (if (> a b)
        result
        (iter (next a) (* (term a) result))))
  (iter a 1))

(4)迭代方式2:分子分母看作一個整體贬循,再進行迭代咸包。

#lang planet neil/sicp
(#%require (only racket/base current-inexact-milliseconds))

(define (fraction n)
  (define start-time (current-inexact-milliseconds))
  (define (fractions-next x) (+ x 1))
  (product fraction-1num 1 fractions-next n)
  (newline)
  (define end-time (current-inexact-milliseconds))
  (display (- end-time start-time)))

(define (fraction-1num n)
  (/ (numerator_num n)
     (denominator_num n)))

(define (numerator_num n)
  (* (+ (quotient n 2)
        1)
     2))

(define (denominator_num n)
  (+ (* (quotient (+ n 1) 2)
     2)
     1))

(define (product term a next b)
  (define (iter a result)
    (if (> a b)
        result
        (iter (next a) (* (term a) result))))
  (iter a 1))

分別使用上述迭代和遞歸方法,計算n=1000杖虾,重復(fù)計算50次烂瘫,記錄下每次運算時間,如下圖所示奇适。

[7]: http://latex.codecogs.com/svg.latex?(itera_{1}result)=(itera_{2}(f(a_{1}){\times}result))=(itera_{3}(f(a_{2}){\times}result))

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末坟比,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子滤愕,更是在濱河造成了極大的恐慌温算,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件间影,死亡現(xiàn)場離奇詭異注竿,居然都是意外死亡,警方通過查閱死者的電腦和手機魂贬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進店門巩割,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人付燥,你說我怎么就攤上這事宣谈。” “怎么了键科?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵闻丑,是天一觀的道長。 經(jīng)常有香客問我勋颖,道長嗦嗡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任饭玲,我火速辦了婚禮侥祭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘茄厘。我一直安慰自己矮冬,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布次哈。 她就那樣靜靜地躺著胎署,像睡著了一般。 火紅的嫁衣襯著肌膚如雪窑滞。 梳的紋絲不亂的頭發(fā)上琼牧,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天径筏,我揣著相機與錄音,去河邊找鬼障陶。 笑死,一個胖子當(dāng)著我的面吹牛聊训,可吹牛的內(nèi)容都是我干的抱究。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼带斑,長吁一口氣:“原來是場噩夢啊……” “哼鼓寺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起勋磕,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤妈候,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后挂滓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體苦银,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年赶站,在試婚紗的時候發(fā)現(xiàn)自己被綠了幔虏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡贝椿,死狀恐怖想括,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情烙博,我是刑警寧澤瑟蜈,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站渣窜,受9級特大地震影響铺根,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜图毕,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一夷都、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧予颤,春花似錦囤官、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至驳庭,卻和暖如春刑顺,著一層夾襖步出監(jiān)牢的瞬間氯窍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工蹲堂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留狼讨,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓柒竞,卻偏偏與公主長得像政供,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子朽基,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容