<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    莊周夢(mèng)蝶

    生活、程序、未來(lái)
       :: 首頁(yè) ::  ::  :: 聚合  :: 管理
        讀《代碼大全2》,已經(jīng)讀了一半,喘口氣。總結(jié)八個(gè)字:百科全書(shū),受益匪淺。小到一個(gè)賦值語(yǔ)句、一個(gè)循環(huán)的編寫(xiě),大到需求分析、架構(gòu)設(shè)計(jì),無(wú)所不包,看后半部分目錄,更是扯到了重構(gòu)、軟件工藝、程序員的性格特征這樣的話題。恰好手邊的工作暫時(shí)比較有閑,可以實(shí)踐下“創(chuàng)建高質(zhì)量的代碼”中的部分建議,晚上讀書(shū),第二天就重構(gòu),樂(lè)在其中。這一部分中對(duì)設(shè)計(jì)、子程序、類、變量、語(yǔ)句的處理建議,可能你平常已經(jīng)在這么做,可作者這么精辟地概括出來(lái)讓人嘆服,而有些地方是你平常絕對(duì)很少注意的,特別是在變量和三種常見(jiàn)控制語(yǔ)句的處理上。
      
        說(shuō)說(shuō)我認(rèn)為是缺點(diǎn)的地方,就是作者貌似對(duì)函數(shù)式語(yǔ)言了解很少,舉的例子全部用的是廣泛應(yīng)用的靜態(tài)語(yǔ)言(c/c++,java,vb)。例如作者有這么一句話:如果為我工作的程序員用遞歸去計(jì)算階乘,那么我寧愿換人。作者對(duì)遞歸的態(tài)度相當(dāng)謹(jǐn)慎,這在靜態(tài)命令式語(yǔ)言中顯然是正確的,但是在函數(shù)式語(yǔ)言中,由于有尾遞歸優(yōu)化的存在,遞歸反而是最自然的形式,況且我打心里認(rèn)為遞歸更符合人類思維。請(qǐng)注意,在FP中只有尾遞歸的程序才是線性迭代的,否則寫(xiě)出來(lái)的遞歸可能是線性遞歸或者樹(shù)形遞歸,兩種情況下都可能導(dǎo)致堆棧溢出并且性能較差。

    scheme寫(xiě)階乘:
    (define (fac n)
      (
    if (= 1 n)
          
    1
          (
    * n (fac (- n 1)))))
    顯然這個(gè)版本不是尾遞歸,計(jì)算過(guò)程是一個(gè)線性遞歸過(guò)程,計(jì)算(fac 4)的過(guò)程如下:
    (* 4 (fac 3))
    (* 4  (3 * (fac 2)))
    (* 4  (3 * (* 2 (fac 1))))
    (* 4  (3 * (* 2 1)))
    (* 4  (3 * 2))
    (* 4 6)
    24
        因?yàn)榻忉屍魇遣捎脩?yīng)用序求值,需要將表達(dá)式完全展開(kāi),然后依次求值,在這個(gè)過(guò)程中,解釋器內(nèi)部需要保存一條長(zhǎng)長(zhǎng)的推遲計(jì)算的軌跡。
    改寫(xiě)成一個(gè)尾遞歸版本:
    (define (fac n)
      (define (fac
    -iter product n)
        (
    if (= 1 n)
            product
            (fac
    -iter (* n product) (- n 1))))
      (fac
    -iter 1 n))
    我們來(lái)看看它的計(jì)算過(guò)程:
    (fac-iter 1 4)
    (fac-iter 4 3)
    (fac-iter 12 2)
    (fac-iter 24 1)
    24
    可以看到,在這個(gè)過(guò)程中,解釋器不需要保存計(jì)算軌跡,迭代的中間結(jié)果通過(guò)product變量來(lái)保存,這是一個(gè)線性迭代的計(jì)算過(guò)程。
    最后再看一個(gè)斐波拉契數(shù)列的例子:
    (define (fib n)
      (cond ((
    = n 0) 0)
                ((
    = n 11)
                (
    else
                     (+ (fib (- n 1))  (fib (- n 2))))))

    這個(gè)計(jì)算過(guò)程展開(kāi)是一個(gè)樹(shù)形遞歸的過(guò)程(為什么說(shuō)是樹(shù)形?展開(kāi)下計(jì)算過(guò)程就知道),改寫(xiě)為線性迭代:
    (define (fib n)
      (define (fib
    -iter a b count)
         (
    if (= count 0)
             b
             (fib
    -iter (+ a b) a (- count 1))))
     (fib
    -iter 1 0 n))

         上述的內(nèi)容在sicp第一章里有更詳細(xì)的介紹和討論。


    評(píng)論

    # re: 用遞歸計(jì)算階乘咋不行呢?  回復(fù)  更多評(píng)論   

    2008-03-18 19:44 by 久城
    不了解函數(shù)式語(yǔ)言,但是《代碼大全》還是很不錯(cuò)的。

    剛進(jìn)公司時(shí)買了一本...

    很遺憾,到現(xiàn)在也沒(méi)看完幾章...

    有時(shí)間要好好學(xué)習(xí)一下了。

    # re: 用遞歸計(jì)算階乘咋不行呢?  回復(fù)  更多評(píng)論   

    2008-03-19 17:20 by CowNew開(kāi)源團(tuán)隊(duì)
    階乘的非遞歸算法也很簡(jiǎn)單呀,不知道為什么很多教科書(shū)講階乘的時(shí)候都用遞歸算法。
    //實(shí)例性代碼,未考慮大數(shù)值的計(jì)算溢出問(wèn)題
    private int calcFact(int value)
    {
    int fact = 1;
    for (int i = 2; i <= value; i++)
    {
    fact *= i;
    }
    return fact;
    }

    # re: 用遞歸計(jì)算階乘咋不行呢?  回復(fù)  更多評(píng)論   

    2008-03-19 17:36 by ZelluX
    @CowNew開(kāi)源團(tuán)隊(duì)
    Thinking in Lisp...

    # re: 用遞歸計(jì)算階乘咋不行呢?  回復(fù)  更多評(píng)論   

    2008-03-19 17:47 by dennis
    @CowNew開(kāi)源團(tuán)隊(duì)
    教科書(shū)上講階乘都是用遞歸算法,這是因?yàn)殡A乘就是用遞歸定義的嘛
    n=1 fac(n)=1
    n>1 fac(n)=n*fac(n-1)

    類似Lisp這樣的函數(shù)式語(yǔ)言能將數(shù)學(xué)公式直接描述出來(lái)(what to do,而非how to do),Lisp本來(lái)就是為了解決符號(hào)推斷而發(fā)展起來(lái)的,比如用Lisp求函數(shù)導(dǎo)數(shù),你能想象用java做出來(lái)嗎?做出來(lái)也夠嗆。

    # re: 用遞歸計(jì)算階乘咋不行呢?  回復(fù)  更多評(píng)論   

    2008-03-19 19:27 by CowNew開(kāi)源團(tuán)隊(duì)
    @dennis
    階乘就是用遞歸定義的嗎?“N的階乘等于1*2*3*4*……*(N-1)*N”

    # re: 用遞歸計(jì)算階乘咋不行呢?  回復(fù)  更多評(píng)論   

    2008-03-19 20:34 by ZelluX
    @dennis
    不是吧。。遞歸定義只是一種表達(dá)形式而已。。
    Lisp只是多了將函數(shù)作為基本類型的特性而已,描述上和其他語(yǔ)言還是一樣的吧,SICP序言中就提到了它們都是imperative的,而不是數(shù)學(xué)中更常見(jiàn)的declarative。
    Java不能求導(dǎo)不就是因?yàn)镴ava沒(méi)函數(shù)指針或者說(shuō)callback機(jī)制不夠強(qiáng)大嗎

    # re: 用遞歸計(jì)算階乘咋不行呢?  回復(fù)  更多評(píng)論   

    2008-03-20 09:15 by dennis
    @ZelluX
    嗯,我得承認(rèn)我的表述很不恰當(dāng),我的本意是Scheme更容易將說(shuō)明性的數(shù)學(xué)公式直接翻譯為表達(dá)式。Lisp模擬函數(shù)求導(dǎo)很容易,除了將 函數(shù)作為一等公民的特性外,更重要的是可以將符號(hào)作為數(shù)據(jù)來(lái)平等對(duì)待,如果用java來(lái)做,恐怕要自己搞一個(gè)類似詞法分析的東東。

    # re: 用遞歸計(jì)算階乘咋不行呢?  回復(fù)  更多評(píng)論   

    2008-03-20 09:40 by ZelluX
    @dennis
    需要什么詞法分析。。
    dy/dx不就行了嗎

    double derivative = (f(x + EPISILON) - f(x)) / EPESILON;

    # re: 用遞歸計(jì)算階乘咋不行呢?  回復(fù)  更多評(píng)論   

    2008-03-20 10:07 by dennis
    @ZelluX
    我說(shuō)的是符號(hào)求導(dǎo),比如求函數(shù)2x^2的導(dǎo)數(shù)是4x

    # re: 用遞歸計(jì)算階乘咋不行呢?[未登錄](méi)  回復(fù)  更多評(píng)論   

    2008-04-08 19:54 by 閑耘
    才知道尾遞歸,學(xué)習(xí)。
    http://blog.xianyun.org/2008/04/08/factorial-and-tail-recursion/

    # re: 用遞歸計(jì)算階乘咋不行呢?  回復(fù)  更多評(píng)論   

    2010-02-01 18:03 by zagfai
    @CowNew開(kāi)源團(tuán)隊(duì)

    無(wú)知...

    函數(shù)式?jīng)]循環(huán)
    主站蜘蛛池模板: 好爽又高潮了毛片免费下载| 日韩免费在线观看视频| 成人毛片18女人毛片免费96| 亚洲精品韩国美女在线| 久久久久免费看成人影片| 久久精品a亚洲国产v高清不卡| 两个人看的www免费视频| 亚洲va国产va天堂va久久| a国产成人免费视频| 亚洲AV无码成人精品区天堂| 无码囯产精品一区二区免费| 久久久亚洲裙底偷窥综合| 亚洲一区二区免费视频| 亚洲xxxxxx| 国产成人免费ā片在线观看| 色爽黄1000部免费软件下载| 亚洲伊人久久大香线蕉综合图片 | 亚洲日韩精品无码一区二区三区| 一区二区三区免费高清视频| 亚洲精品美女久久久久99| 你懂的免费在线观看网站| 亚洲毛片一级带毛片基地| 野花高清在线电影观看免费视频| 亚洲综合一区国产精品| 国产成人3p视频免费观看| 好猛好深好爽好硬免费视频| 精品无码一区二区三区亚洲桃色| 很黄很色很刺激的视频免费| 亚洲精品美女久久7777777| 亚洲性猛交XXXX| 精品福利一区二区三区免费视频 | 亚洲精品国产成人影院| 成人久久免费网站| 日韩亚洲国产综合高清| 中文字幕精品亚洲无线码一区 | 无码国模国产在线观看免费| 中国一级特黄的片子免费 | 亚洲国产精品婷婷久久| 成人网站免费观看| 男女一边桶一边摸一边脱视频免费 | 一级做a爰全过程免费视频|