青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-341  評論-2670  文章-0  trackbacks-0

    接著上一篇文章繼續往下講。如果按照上一篇文章走下去的話,現在估計做了有些小軟件了吧。字符串和圖形都容易做大,而且對于潛意識上喜歡數學的最有希望的程序員們也是有吸引力的。但是這兩種東西卻不容易做好。等到程序到了一定規模的時候,維護和效率這兩大問題就會凸顯出來。心急吃不了熱豆腐,為了解決維護和效率這兩個經常會出現的問題,我們需要學習算法和架構。這兩種東西是可以同時學的,但是一篇文章說不了多少東西,那么就從算法開始吧。

    程序員是需要開闊眼界的,光C#一門也是不行的,畢竟程序運行在各種平臺上,有各種各樣的語言。譬如Win32上的native C/C++、Delphi等,.NET上的C#和VB.NET,還有自成體系的Java,然后就是運行在mainframe上的COBOL,剩下的還有各種各樣的函數式語言、腳本語言等等。熟悉了C#的人從Delphi入手不會很困難,從C/C++入手也可以了。這兩門原本是本地語言的語言在編寫程序的時候需要我們注意多一些的東西,典型的就是內存管理。這還是需要多加練習的,在這里就不多說了。

    說到算法,在這里首先向大家推薦《算法導論》第二版。一年前我去買的時候,發現了中文版,但是中文版那個時候仍然有一些章節沒有翻譯。不知道現在怎么樣了。英語好的同志們可以去買英文版。

    算法與數據結構是經常出現在一起的。每一種算法總會有在各種不同數據結構上的實現,用于處理不同的問題。在不同的語言上面,各種各樣針對實際問題的數據結構也有一些巧妙的做法和通用的做法。我們可以用STL,可以用System.Collections.Generic,也可以自己寫。這根據實際情況而定。我們并不是不能做的比STL好,只是STL已經相當好了,滿足了大多數人的需要。在特定的情況下,面對非常特殊的問題,有時候我們就要自己實現數據結構。使用上一篇文章說的辦法來聯系的話,到了這個時候已經寫了不少代碼了,用了不少并不復雜的數學知識了,鍛煉了理論與實際相聯系的基礎。有了這些基礎,我們學習算法和數據結構會比較簡單。

    常用的數據結構有鏈表、列表、堆棧、隊列、二叉樹、平衡樹、堆、哈希表和圖等,除此之外還有各種各樣的變形,但是萬變不離其宗。圍繞著這些數據結構還有各種各樣的算法。典型的有排序算法、搜索算法、尋路算法、網絡流等等。還有一些屬于策略的算法,譬如貪心算法、動態規劃等等。屬于策略的算法經常用于制造新的算法,要慢慢體會,勤加思考才行。至于這些數據結構和算法的實際內容我并不打算在這篇文章講。《算法導論》用了半本書來說這些問題,還是看書的好,文章不夠詳細。

    至于我們如何選擇算法呢?就如同我剛才強調的一樣,我們需要聯系理論與實際的經驗,我們要用數學的眼光來看待我們需要解決的問題。如果我們找到了一種簡潔的表示來描述我們的問題的話,我們同時也找到了解決問題需要的數據結構的雛形。當然這個數學并不是指數學分析這些,我覺得更接近于抽象代數。扯遠了啊,一般來說我們并不需要鉆研這些學科,我們只需要有感覺就好了。培養感覺的一個捷徑就是學習數學。當然不學習也可以,經驗也能知道我們做事情,只不過走的路要長一些。至于讀者希不希望學習數學就自己決定吧,沒有普適的道路。找到了數據結構的雛形之后,剩下的就是尋找算法了。有一些算法可以在書里面找到(譬如ACM很喜歡考的題目),有一些算法可以在論文中找到(譬如專門為了對付一些復雜問題而制造出來的不具有通用性的算法),剩下的就要靠我們自己去推導了。

    那么,我們如何學習算法呢?我們是為了解決實際問題才學習算法的,是為了為將來自己遇到問題的時候有個指導方向才學習算法的,我們并不是為了學習算法而學習算法。我見過兩種不同的學習算法的人。第一種是直覺閱讀算法并學習,以后碰到問題再尋找。另一種則是僅僅將算法稍微了解一下然后就放開,以后遇到問題的時候再翻開相應的算法來學習。兩種方法適應于兩種不同的人,并沒有什么大的優劣之分。于是我們根據自己的興趣或者需要,終于必須掌握一種算法了。那么這個時候我們可以找資料來看,就跟閱讀文章一樣消化里面的知識,然后就寫一些小程序來試驗試驗(或者叫做原型,那些做軟件工程的人都喜歡這么說)。這種小程序屬于拋棄型原型,寫完即扔的,目的是為了讓自己在了解了算法的內容之后,檢驗一下自己是否已經真的明白了執行這個算法所需要的所有細節問題。等到覺得自己已經能控制這個算法的時候,我想也就差不多了吧。

    有些人可能會覺得算法很復雜,因為書里面的算法都是非常復雜的。但是算法的目的是為了快,因此有一些好的算法跟數據結構,結合的時候可能會變得相當簡單,但是并不是很容易想到。在這里我舉幾個簡單的例子。

    喜歡做圖形的朋友們,大概都喜歡做游戲吧,嘿嘿。我們小時候在做那種簡單的2D游戲的時候,總是要計算一大堆人之間是否相互接觸,或者很多人放出的魔法是否跟敵人碰撞到。如果我們的地圖上有100個人,每個人放了兩招,兩兩檢驗是否碰撞(以便判斷是否應該實施攻擊)的話就需要檢查20000次。這顯然是不行的。那么我們可以使用分而治之的原理來做。我們可以把地圖切成很多個區域,區域包含著人和魔法。每當人和魔法的移動越過區域的邊界的時候,人和魔法就把自己從前一個區域斷開,鏈接到新的區域里面去。這個時候區域就保存了兩個鏈表,一個是人,另一個是魔法。好了,如何檢查魔法和人互相碰撞呢?只需要檢查同一個區域里面的就行了。如果這100人都在25個區域里面,平均每個區域有4個人8個魔法,那么兩兩檢驗的話只需要檢查4×8×25=800次,相對于前面的暴力算法節省了96%的時間。當然這只是理想狀態。

    在這里舉另一個例子。我們都覺得C#、VB和Java很神奇吧,東西new了都不用delete,多舒服。假設我們現在要實現這種功能的話,我們需要維護所有已經new了的內存空間,并執行一種搜索算法來判斷哪一些內存空間是再也不可能被訪問的然后標記,最后刪掉所有被標記的空間。于是我們需要一個內存管理器,用來申請、標記和釋放。如何做比較合適呢?

    我們的內存管理器需要根據設置的長度返回一段句柄來代表內存空間,然后需要可以通過句柄來訪問內存,最后標記并一起刪除這些句柄。為什么要句柄呢?因為如果直接返回指針的話,語言執行久了會產生很多內存碎片,而且new和delete也不夠快。現在,我們需要以下幾個數據結構:

    ·一個記錄所有被new了而且delete過的句柄的列表,用于迅速獲得沒有正在被使用的句柄。
    ·一個記錄了所有正在使用的句柄的列表,記錄指針以及長度。這張表是一個數組,句柄是索引。

    new的時候,我們查詢第一張表拿出一個空閑的句柄。如果列表為空的話那么將第二個表變大(這個時候所有句柄都被使用)并且將第一個空閑的(也就是原來的表接下去的第一個新空間)句柄所對應的記錄標記使用。然后我們分配的總是最末尾的地方
    delete的時候,我們查詢所有標記了使用句柄,看看是否有被mark,有的話就標記為不使用并將句柄放置入第一張表。
    mark的時候,我們查詢這個句柄所對應的記錄,然后mark。
    collect的時候,這是一個操作,將所有內存碎片清除。我們只需要順序遍歷第二章表,將有用的內容挪動到前面一大塊無用的空間里面,復制一下數據然后修改一下起始指針即可。

    圖示一下:
    空閑句柄:1 2
    句柄記錄:<0,0..9><1,NULL><2,NULL><3,40..43>
    內存空間:[第0-9個字節占用][10-39不占用][40-43被占用][此處為末尾]

    好了,我們需要申請一個內存空間,我們拿到了句柄4,需要10個字節。
    空閑句柄:1 2
    句柄記錄:<0,0..9><1,NULL><2,NULL><3,40..43><4,44..53>
    內存空間:[第0-9個字節占用][10-39不占用][40-43被占用][44-53被占用][此處為末尾]

    現在我們標記3并刪除:
    空閑句柄:1 2 3
    句柄記錄:<0,0..9><1,NULL><2,NULL><3,NULL><4,10..19>
    內存空間:[第0-9個字節占用][10-19占用,從句柄4挪過來的][此處為末尾]

    分析一下時間復雜度吧,這里分析的是絕大部分情況,根據數據結構的實際實現偶爾會有少許偏差。
    new為O(1),因為從空閑句柄獲得內容為O(1),分配末尾內存為O(1),找到記錄并標記為O(1)
    mark為O(1),因為找到記錄并標記為O(1)
    delete為O(1),因為只需要標記
    collect為O(n),因為遍歷句柄記錄O(n),挪動內容,就算最多也就挪動整段內存空間,也是O(n)
    從句并獲得內存地址也是O(1)

    我們僅僅需要在內存不夠的情況下才動用win32的api分配一塊新的大內存,這樣來看的話在大部分情況下我們的內存管理器的分配比操作系統做得還快,這也是為什么C#作為托管語言并沒有明顯慢下來的一個原因。當然還有一些其他原因,譬如.NET虛擬機會把一些托管代碼臨時編譯成本地代碼等等。

    至于第三個例子,就看這里吧,為了做一個大作業而弄出來的利用動態規劃是顯得簡單尋路算法。

    說到這里本篇也快結束了。舉著兩個例子只為了說明以下問題:
    ·算法往往跟執行效率有很大關系
    ·好的數據結構才能發揮算法應有的威力
    ·要根據實際情況來選擇,甚至自己思考算法
    ·算法并不都是復雜的

    其實,對于數據結構和算法不熟悉或者根本沒聽說過的話,也并不是就不能寫出一些稍微有點規模的程序,只是寫出來的程序可能會很亂。算法在一個程序員的發展道路上看還是最好學一學。

posted on 2008-06-11 00:03 陳梓瀚(vczh) 閱讀(9235) 評論(8)  編輯 收藏 引用 所屬分類: 啟示

評論:
# re: 如何學習編程(二) 2008-06-11 02:38 | foxtail
哈哈 這些文章很適合初學者看。thx  回復  更多評論
  
# re: 如何學習編程(二) 2008-06-11 17:43 | PPPPPPPPPPPPP
其實我們沒有必須多學一種語言,其實C#也可以編譯成本機代碼的,只是國外沒有這樣作罷了,其實C++也可以把智能提示做的很好,只是國外沒有這樣作罷了,。。。只有把這些分開才能讓你分別為它付費。。這是市場因素,不是技術原因,國外的編譯器很發達,可以把一段C#代碼分別編譯成本機與托管的  回復  更多評論
  
# re: 如何學習編程(二) 2008-06-11 18:16 | 陳梓瀚(vczh)
可惜這是中國,不是什么公司都愿意培訓你的。精要一門,會的要很多。而且既然人家把市場因素強加到你身上,而且你有改不了的話,那還是適應一下罷了。

做庫的人跟做應用的人考慮的方向還是不同的。雖然我還是偏向于做庫,不過應用層面的東西還是要了解以下為好,至少可以對付突發事件。  回復  更多評論
  
# re: 如何學習編程(二) 2008-06-11 18:33 | 路過
第二段基本沒有對的地方  回復  更多評論
  
# re: 如何學習編程(二) 2008-06-11 21:24 | 陳梓瀚(vczh)
能否說說你自己的看法?  回復  更多評論
  
# re: 如何學習編程(二) 2008-06-12 01:10 | jx
@PPPPPPPPPPPPP
只會一種語言的是傻帽,沒必要學了C#又學Java,但是起碼應該學學Lisp或Haskell等某種函數式編程,不會函數式編程也甭想學好腳本語言,C#不是也有函數式的特性嗎?你丫了解嗎?只會一種語言打工都打不好。  回復  更多評論
  
# re: 如何學習編程(二) 2008-06-12 02:18 | 陳梓瀚(vczh)
我自己實現過函數式語言,我之前的一篇關于閉包的實現也舉了c#的例子,請過目。
http://www.shnenglu.com/vczh/archive/2008/04/21/47730.html  回復  更多評論
  
# re: 如何學習編程(二) 2010-02-14 11:45 | 煙皚
看了一和二,收獲頗多,目前也在一種學習迷茫的狀態,方向很模糊,只能走一步看一步。現看了博主的文章,感覺清晰了不少,thanks了~  回復  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲国产欧美一区二区三区久久| 亚洲人在线视频| 一本色道久久综合一区| 欧美激情网友自拍| 在线亚洲欧美专区二区| 亚洲天堂男人| 国产自产在线视频一区| 欧美黄污视频| 欧美日韩国产一区二区三区地区 | 国产日韩欧美另类| 久久精品盗摄| 浪潮色综合久久天堂| 欧美国产三区| 欧美日韩人人澡狠狠躁视频| 亚洲欧美在线播放| 久久久久久夜| 亚洲欧美日本日韩| 久久精品卡一| 亚洲欧美日韩区| 欧美1区2区3区| 欧美亚洲网站| 欧美顶级艳妇交换群宴| 欧美一区二区视频97| 欧美国产日韩精品| 久久久九九九九| 欧美激情bt| 久久噜噜噜精品国产亚洲综合| 欧美劲爆第一页| 久久久久综合| 国产精品欧美久久| 亚洲福利视频专区| 国外视频精品毛片| 亚洲一区二区免费在线| 亚洲人成人77777线观看| 午夜精品久久久久| 亚洲一区二区三区精品在线观看| 久久久久久久999| 欧美中文字幕第一页| 国产精品电影观看| 亚洲日本视频| 亚洲日本欧美在线| 久久久蜜臀国产一区二区| 性色一区二区| 国产精品进线69影院| 亚洲欧洲另类| 亚洲国产精品女人久久久| 欧美专区日韩视频| 一区二区三区黄色| 伊人久久男人天堂| 香蕉久久夜色精品国产| 中文亚洲欧美| 欧美日韩1区| 亚洲经典三级| 亚洲看片免费| 欧美成人自拍| 亚洲人被黑人高潮完整版| 亚洲国产视频直播| 免费成人av| 亚洲成人在线视频播放| 亚洲国产精品久久久久婷婷老年| 久久久综合激的五月天| 久热国产精品| 亚洲日本久久| 欧美日韩精品免费看| 亚洲卡通欧美制服中文| 99ri日韩精品视频| 欧美日韩在线大尺度| 中日韩美女免费视频网站在线观看| 夜夜嗨av一区二区三区中文字幕| 欧美精品成人一区二区在线观看 | 亚洲欧美一级二级三级| 国产精品久久久久高潮| 午夜精品久久久久久久男人的天堂| 欧美一区影院| 黄色亚洲在线| 欧美风情在线| 在线一区日本视频| 久久国产欧美| 亚洲人成网站777色婷婷| 国产精品99久久久久久久vr | 激情五月***国产精品| 久久久久久高潮国产精品视| 国产亚洲欧美另类中文| 久久久久久夜| 亚洲精品在线二区| 午夜国产精品影院在线观看| 国产一区二区三区四区| 美玉足脚交一区二区三区图片| 亚洲人成毛片在线播放女女| 亚洲欧美日韩中文播放| 黄色日韩在线| 欧美性大战久久久久| 亚洲欧美在线网| 亚洲经典自拍| 欧美一激情一区二区三区| 一区二区视频免费完整版观看| 欧美日韩国产欧| 欧美影院一区| 亚洲日本欧美在线| 久久深夜福利| 亚洲性视频网站| 极品裸体白嫩激情啪啪国产精品| 欧美激情按摩在线| 午夜精品视频| 日韩视频免费观看| 久久夜色精品| 亚洲欧美综合一区| 亚洲精品久久久久久下一站 | 亚洲国产成人精品久久| 国产精品国产三级国产普通话蜜臀 | 黄页网站一区| 欧美视频一区二区在线观看| 久久久亚洲高清| 亚洲一二三区在线观看| 亚洲国产精品嫩草影院| 久久久久久黄| 欧美一区二区三区视频| 一本大道久久a久久综合婷婷| 伊甸园精品99久久久久久| 国产伦精品一区二区三区免费迷| 欧美精品久久久久久久免费观看| 久久免费视频观看| 香蕉久久精品日日躁夜夜躁| 亚洲最新在线| 亚洲精品日韩欧美| 亚洲国产欧美一区二区三区丁香婷| 久久久久国产一区二区三区四区 | 久久久久久久尹人综合网亚洲| 亚洲无线一线二线三线区别av| 亚洲国产日韩在线一区模特| 精品成人国产| 一区二区在线看| 樱桃国产成人精品视频| 国产人久久人人人人爽| 国产欧美日韩综合一区在线观看 | 国内精品模特av私拍在线观看| 国产精品亚洲欧美| 国产精品一级二级三级| 欧美午夜免费影院| 国产精品久久婷婷六月丁香| 欧美三级日韩三级国产三级| 欧美日韩亚洲一区二区三区| 欧美二区不卡| 欧美日韩一区二区在线观看| 欧美日产国产成人免费图片| 欧美日本一区二区高清播放视频| 欧美区在线播放| 国产精品久久久久久久电影 | 亚洲影院免费| 欧美一区二区在线视频| 久久精品中文字幕免费mv| 久久嫩草精品久久久精品一| 久久在线视频在线| 欧美freesex8一10精品| 亚洲国产天堂网精品网站| 亚洲精品久久久久久久久久久久 | 看欧美日韩国产| 欧美激情一区三区| 国产精品人人爽人人做我的可爱| 国产日韩欧美日韩| 91久久嫩草影院一区二区| 一区二区日韩欧美| 久久精品国产久精国产爱| 欧美成人69av| av不卡在线| 久久超碰97中文字幕| 欧美jjzz| 国产精品推荐精品| 在线精品视频在线观看高清 | 国产日韩一区| 亚洲精品久久7777| 午夜久久久久久| 欧美高清在线| 亚洲一卡二卡三卡四卡五卡| 国产亚洲美州欧州综合国| 亚洲黄页视频免费观看| 亚洲天堂成人在线观看| 久久综合导航| 日韩视频专区| 久久一综合视频| 国产精品黄页免费高清在线观看| 在线播放国产一区中文字幕剧情欧美| 日韩午夜激情| 久久成人18免费网站| 亚洲国产成人精品久久| 亚洲曰本av电影| 欧美日本三区| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲欧美色婷婷| 亚洲三级免费电影| 久久男人av资源网站| 国产精品美女久久久久久久| 亚洲激情欧美| 久久亚洲精品视频| 亚洲欧美久久| 国产精品久久久久久福利一牛影视| 亚洲精品久久久久久久久久久久| 久久嫩草精品久久久精品| 亚洲在线播放| 国产精品欧美在线|