教你學演算法
1. 竟然是個教演算法的老師
如果你真是要學習編程,而編程不是為了競賽、考試,那麼你遇上一位教演算法的老師真是有福了。
有空你可問問你的老師,如何看待Donald E. Knuth所寫的《計算機程序設計藝術》,你就會知道演算法對你的學習是多麼的有幫助。
比爾蓋茨曾說過,「如果你認為你是一名真正優秀的程序員,就去讀第一卷,確定可以解決其中所有的問題。」「如果你能讀懂整套書的話,請給我發一份你的簡歷。」
這本書有三卷:
The Art of ComputerProgramming:
1.Fundamental Algorithms; 《基本演算法》
2.Seminumerical Algorithms;《半數值演算法》
3.Sorting andSearching。《排序與查找》
我現在收集到2、3卷的中文版(34MB)和1、2、3卷的英文版,PDF文件。 誰有第1卷中文版,告訴我。
2. 演算法怎麼學
貪心演算法的定義:
貪心演算法是指在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,只做出在某種意義上的局部最優解。貪心演算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有關。
解題的一般步驟是:
1.建立數學模型來描述問題;
2.把求解的問題分成若干個子問題;
3.對每一子問題求解,得到子問題的局部最優解;
4.把子問題的局部最優解合成原來問題的一個解。
如果大家比較了解動態規劃,就會發現它們之間的相似之處。最優解問題大部分都可以拆分成一個個的子問題,把解空間的遍歷視作對子問題樹的遍歷,則以某種形式對樹整個的遍歷一遍就可以求出最優解,大部分情況下這是不可行的。貪心演算法和動態規劃本質上是對子問題樹的一種修剪,兩種演算法要求問題都具有的一個性質就是子問題最優性(組成最優解的每一個子問題的解,對於這個子問題本身肯定也是最優的)。動態規劃方法代表了這一類問題的一般解法,我們自底向上構造子問題的解,對每一個子樹的根,求出下面每一個葉子的值,並且以其中的最優值作為自身的值,其它的值舍棄。而貪心演算法是動態規劃方法的一個特例,可以證明每一個子樹的根的值不取決於下面葉子的值,而只取決於當前問題的狀況。換句話說,不需要知道一個節點所有子樹的情況,就可以求出這個節點的值。由於貪心演算法的這個特性,它對解空間樹的遍歷不需要自底向上,而只需要自根開始,選擇最優的路,一直走到底就可以了。
話不多說,我們來看幾個具體的例子慢慢理解它:
1.活動選擇問題
這是《演算法導論》上的例子,也是一個非常經典的問題。有n個需要在同一天使用同一個教室的活動a1,a2,…,an,教室同一時刻只能由一個活動使用。每個活動ai都有一個開始時間si和結束時間fi 。一旦被選擇後,活動ai就占據半開時間區間[si,fi)。如果[si,fi]和[sj,fj]互不重疊,ai和aj兩個活動就可以被安排在這一天。該問題就是要安排這些活動使得盡量多的活動能不沖突的舉行。例如下圖所示的活動集合S,其中各項活動按照結束時間單調遞增排序。
關於貪心演算法的基礎知識就簡要介紹到這里,希望能作為大家繼續深入學習的基礎。
3. 如何提高演算法
計算的准確性不但在「應試教育」中佔主要地位,在「素質教育」的今天同樣重要。因為式子題的計算是學生解決實際問題的基礎,是每個小學生必須掌握的數學基礎知識和基本技能。只有計算過硬,才能進一步學好應用題和其他學科知識。式子題計算是各年級的重要內容,根據學生的考試和作業看,造成成績不理想的原因是計算能力差,准確率不高。造成這種現象的原因是多方面的:首先是低年級忽略了口算訓練,其次是在各年級中輕視了式子題的教學,誤認為計算式子題只要弄清計算順序,便能算出來,這種想法造成學生計算不細心,准確率低,從而缺乏攻克復雜式子題的興趣和信心。
計算準確,要從低年級抓起,不僅要教學生演算法,更要重視口算的訓練。口算是筆算、估算的基礎,只有讓學生在理解的基礎上掌握了口算的方法,堅持練習,逐步達到熟練的程度,才會在中、高年級中熟練、准確地計算。同樣,中高年級也不能忽視口算的練習。
式子題的訓練,還要從讀題做起,讀題要求學生正確規范,這樣有助於弄清運算順序。有括弧題,如(a+b)c,可讀作a與b的和乘以c,不能把括弧讀出來,嚴格要求學生讀准,從中悟出運算順序,確定自己的演算法。弄清計算順序是計算的前期。不這樣訓練,學生容易忽略和弄錯順序,對「准確」沒有把握,長期這樣,學生會對數學失去信心,失去積極性,教師也會對學生的計算失去信心。
文字題是式子題的讀題與列式計算的訓練,在讀題的基礎上,讓學生列出算式,正反結合訓練,會對學生的計算進行強化。文字題既然是計算題的敘述,那麼解決文字題就是列出綜合算式,它與應用題的解答有別,不能用分步計算,但可以用分步式分析。分析後列出綜合計算是解決文字題的正確做法。
加強運算定律和運算性質的教學,多用於實際計算,讓學生充分理解算理,掌握法則,鼓勵學生運用簡便演算法。除題目要求簡算外,教師要有意識地要求學生能簡算的奧運用簡算,提高學生的簡算興趣,使簡算貫穿於一切計算之中,逐步摸索計算的技巧,做到計算合理,靈活,准確,迅速,有力的提高學生的計算能力。
計算準確性的訓練要常抓不懈,養成檢查、驗算的習慣。對於一般的學生,式子題做完了不願意檢查、驗算,造成准確率低的現象。針對這種現象,要有意識的訓練,培養學生驗算,長此以往,「准確」就有保證了。
在式子題的計算中,採用適當的計算方法也要給與指導和練習。如高年級的分數、小數、百分數的混合運算,要根據題和自己的特長確定具體演算法。讓學生針對題型動腦思考,自做練習,在和他人比較,找到巧妙的演算法,也是准確性的訓練。
對學生經過長期多方面的計算訓練,培養學生嚴格、認真、對計算結果負責的良好習慣以及有毅力、肯動腦、克服困難的意志,學生的計算能力就會明顯提高,為下一步學習打下堅實基礎
4. 小學數學有哪些簡便演算法,你知道嗎
對於那些成績較差的小學生來說,學習小學數學都有很大的難度,其實小學數學屬於基礎類的知識比較多,只要掌握一定的技巧還是比較容易掌握的.在小學,是一個需要養成良好習慣的時期,注重培養孩子的習慣和學習能力是重要的一方面,那小學數學有哪些技巧?
一、重視課內聽講,課後及時進行復習.
新知識的接受和數學能力的培養主要是在課堂上進行的,所以我們必須特別注意課堂學習的效率,尋找正確的學習方法.在課堂上,我們必須遵循教師的思想,積極制定以下步驟,思考和預測解決問題的思想與教師之間的差異.特別是,我們必須了解基本知識和基本學習技能,並及時審查它們以避免疑慮.首先,在進行各種練習之前,我們必須記住教師的知識點,正確理解各種公式的推理過程,並試著記住而不是採用"不確定的書籍閱讀".勤於思考,對於一些問題試著用大腦去思考,認真分析問題,嘗試自己解決問題.
二、多做習題,養成解決問題的好習慣.
如果你想學好數學,你需要提出更多問題,熟悉各種問題的解決問題的想法.首先,我們先從課本的題目為標准,反復練習基本知識,然後找一些課外活動,幫助開拓思路練習,提高自己的分析和掌握解決的規律.對於一些易於查找的問題,您可以准備一個用於收集的錯題本,編寫自己的想法來解決問題,在日常養成解決問題的好習慣.學會讓自己高度集中精力,使大腦興奮,快速思考,進入最佳狀態並在考試中自由使用.
三、調整心態並正確對待考試.
首先,主要的重點應放在基礎、基本技能、基本方法,因為大多數測試出於基本問題,較難的題目也是出自於基本.所以只有調整學習的心態,盡量讓自己用一個清楚的頭腦去解決問題,就沒有太難的題目.考試前要多對習題進行演練,開闊思路,在保證真確的前提下提高做題的速度.對於簡單的基礎題目要拿出二十分的把握去做;難得題目要盡量去做對,使自己的水平能正常或者超常發揮.
由此可見小學數學的技巧就是多做練習題,掌握基本知識.另外就是心態,不能見考試就膽怯,調整心態很重要.所以大家可以遵循這些技巧,來提高自己的能力,使自己進入到數學的海洋中去.
5. 學習java編程時,什麼時候學習演算法好點
java裡面本身是包含演算法的,只不過它的演算法比著大數據python 那些,還是顯得有點low的。在java編程學習的過程中,你會接觸到一些排序,比如冒泡排序,選擇排序,希爾排序,歸並排序等,這可以當作是學習演算法的入門吧。下面我們從幾個階段來討論:
1.學習階段
剛開始學習java編程,主要還是熟悉它的基本語法,以及常用的框架,做到能夠開發企業級項目,對於一些演算法你可以作為了解,畢竟初級階段,你出去面試找工作,人家也不會難為你問到一些復雜的演算法。
2.工作階段
這個階段你已經步入職場了,在職場中,你會發現,演算法幾乎用不到,可能是你還沒到那個價格,但是這並不意味著,你就不需要學習演算法了。相反,在你工作的同時,你就要留意公司裡面所用的框架,關鍵的技術點,尤其是用到的演算法。有了大致了解後,你就需要利用你工作之餘的時間,開始學習演算法了,因為你不會是想當一輩子的程序員吧?不想的話,你就要下足功夫去學演算法,開源的框架等。
綜上所述,你在學習階段學習一些簡單的演算法,以及對演算法有一個大致的了解,就足夠了。而且在吉林北大青鳥學習期間,老師自然會教什麼時候才是你學習演算法的好時機。
6. C語言裡面的演算法覺得很難,這樣才能學好演算法
學好C語言首先要學好他的語法,就比如說英語和語文,你必須要學好他的語法啊,並且要會用他的」單詞」,然後就是演算法了,這其中要有數學的計算和思想,但是你可以學好的,如果你學好VB那就更好了,因為VB和C語言、很都語法都是共通的.C重要的是思想和演算法..
如果要成為高手的話,那就必須數學基礎扎實,因為要到高級的話會用到很多的函數問題,編程也要邏輯性好,而且C就是一種模式,找到了很容易學的。
說實在的,有些東西當初我拿到書的時候是天天琢磨,月月思考,還真別說,有些當初我以為超級老難的問題就愣是這么給琢磨出來了。不過前提是我的數學和邏輯思維真的不錯。
慢慢來啊,呵呵,就像當初我以為我自己也學不會,結果還是讓我給征服了。其實入門比較困難一些,這都是過程,保持好的心態,如果真的想學就不要放棄,經過時間的積累我想一切都會晴朗的。
7. 演算法該怎麼學感覺好難
很多人都會說"學一樣東西難",一開始我也覺得很大程度是因為每個人的智力水平等等不可改變的因素. 但是後來我發現,有一個東西也很能決定一個人是否會覺得一樣東西難學,那就是理解方式.
一件事物通過不同的途徑讓一個人理解效果差異是很大的.就比如說數學裡面教你一個圓,有的人看到一個圓就能很快明白什麼是圓,有的人卻非得看到x^2+y^2 = r^2這種式子才有感覺,甚至有的人需要"到定點距離為定長的點集"這種描述才能理解. 那這個不一定是說誰的智力水平更高,而是因為他們對不同形式事物的敏感程度不同.
回到演算法上來.演算法本質是一種數學.他是抽象的操作集合.(看這么說你可能會覺得不知所雲,但是如果我說他只是一種解決問題的辦法可能就好理解). 所以很多書,論文,或者很多老師教的都是一種數學描述的演算法,這樣子的演算法就我個人而言相當難理解,看了就想到代數高數什麼的.. 但是如果找一個圖文並茂的解釋,或者找個人一步一步把一個演算法給你我比劃一下,我立刻就能理解. 說白了,就是你一定要找很多很多不同的角度來嘗試接受一種東西,你一定可以找到一種你相當敏感的角度,用這個角度學習你就會游刃有餘. 智力因素並沒有太大影響的.
具體點說,你可以試試這幾種不同的角度.
直接看數學形式的演算法.我個人最無法接受的形式,但是有人很喜歡..例子就是演算法導論上面那種描述.
聽一般語言描述,最理想是找一個明白的人,給你用通俗語言講講原理.這個不錯,很多我是這么理解的
圖形理解,叫理解的人給你畫插圖,分布圖,結構圖等等,來分解一個演算法,找到他的思路.說到圖,有一個人的博客這方面做得很好:matrix67.
程序理解.找到一種演算法的實現程序,對著程序理解,可以嘗試分布運行,觀察一下變數的變化,這樣來理解演算法.
實在太難的演算法,可以邊寫邊改來理解.當時我學習插頭dp的時候就是這樣,不論怎麼總是一知半解,最後硬著頭皮寫了一遍,改了很久,但是改過了的時候,也就真的明白了是怎麼回事了.
也許還有別的什麼辦法,因為人對事物的接受角度實在是太多了.多想想你平時學習什麼比較容易,找出你最敏感的理解方式就行了.
有感而發說的一些東西,不一定都是正確的,只供參考,歡迎指正.
8. 演算法到底應該怎麼學
刷與不刷ACM ICPC的人在演算法能力上會有巨大差距。
如果真想深入掌握各種演算法,還是先刷題吧。刷到一定境界再去看更高級的演算法書。
不得不承認現實生活中,一般碼農工作對演算法能力要求太低了,這一度讓人們(包括我)認為演算法似乎不那麼重要。其實學習演算法所鍛煉出來的對各種問題敏感的反應和融會貫通能力還是非常重要的。
編程嘛,就是操作數據輸出結果
演算法和數據結構是配套的,你應該掌握的主要內容應該是:
這個問題用什麼演算法和數據結構能更快解決
這就要求你對常見的結構和演算法了熟於心,你不一定要敲代碼,用紙手寫流程是更快的方式。
對你不懂的數據結構,你要去搜它主要拿來幹嘛的,使用場景是什麼。
細節出錯是你對編程語言不熟悉才會導致的問題,跟你懂不懂演算法沒關系,這個你應該多寫寫練手小程序,背代碼是很愚蠢的行為。
其實我覺得你這么迷茫不如實現一下stl的函數好了
我的經驗就是去模擬(當然模擬只限於基礎的演算法)。甚至是手動模擬,比如我之前學深搜,學遞歸,代碼很簡單,但是因為涉及到棧,而你的大腦短時間內存儲的棧深度只有幾層(臨時變數越多你大腦能模擬的棧深度就越少),實際上你沒辦法用大腦去想。比如學習圖的深搜,一開始我是不理解的,對遞歸沒辦法理解。後來我就在紙上模擬出來,建立好鄰接表以後,按照代碼步驟一步步紙筆來模擬,慢慢就知道了代碼的工作過程。你學習快排也是,當然你背代碼也能寫出來,但是可能不理解,很快就忘了。《演算法導論》書上就有比較細致的執行過程,你手動模擬下partition和quicksort的過程,一開始就用很簡單的用例,把整個過程都手動執行一遍,慢慢就了解了。很多演算法都有一個循環不變式,你代碼如果邏輯正確並且能夠維持循環不變式,一般寫出來就是正確的。
建議找本《演算法》或者《演算法導論》這些教材,每學習一個演算法就先大致瀏覽下, 然後細致分析每一步代碼的執行過程(紙筆模擬或者代碼單步調試),當確認你真正明白之後,嘗試不看代碼就靠對演算法過程的了解和正確的邏輯去自己實現。
當然,我不認為你寫出很多演算法就是高手了,現在大部分高級語言不需要你重復造輪子,你造出來的質量也遠遜於庫中那些高手的代碼,可以去學習他們代碼的實現,比如看看stl源碼。真正工程用到的代碼與一般演算法實現還是有很多改進的。
最重要的不是你會寫這些演算法了,而是學會了很多思想。比如二分的思想,遞歸的思想,分治的思想,動態規劃,貪心等,以及現實中很多數據結構的抽象等。難的不是學會了演算法,而是如何運用這些演算法思想去解決問題。
9. 初學者如何學演算法
先看看兩本書,一本數據結構,一本離散數學。。。看完以後你就會。。。。