當前位置:首頁 » 便宜好貨 » 演算法為什麼不好理解

演算法為什麼不好理解

發布時間: 2022-08-12 00:06:35

1. 我對計算機的演算法總是理解的不透徹,書上理論的東西有點看不太懂,誰能形象的舉個例子說明

演算法,如果拋開計算機,就是解決問題的方法,類比到計算機,就是要計算機解決問題的方法,演算法不是計算機中獨有的,所以解決方法都可以叫演算法,諸如用火燒水,用杯裝水,也是一個演算法.
計算機中,拿書上來說,演算法就是程序的靈魂.也就是讓計算機通過你"教"他,讓他有解決這種問題的方法的方法就是演算法

2. 演算法怎麼就這么難

廣大碼農同學們大多都有個共識,認為演算法是個硬骨頭,很難啃,悲劇的是啃完了還未必有用——除了面試的時候。實際工程中一般都是用現成的模塊,一般只需了解演算法的目的和時空復雜度即可。

不過話說回來,面試的時候面演算法,包括面項目中幾乎不大可能用到的演算法,其實並不能說是毫無道理的。演算法往往是對學習和理解能力的一塊試金石,難的都能掌握,往往容易的事情不在話下。志於高者得於中。反之則不成立。另一方面,雖說教科書演算法大多數都是那些即便用到也是直接拿模塊用的,但不幸的是,我們這群搬磚頭的有時候還非得做些發明家的事情:要麼是得把演算法當白盒加以改進以滿足手頭的特定需求;要麼乾脆就是要發明輪子。所以,雖說面試的演算法本身未必用得到,但熟悉各種演算法的人通常更可能熟悉演算法的思想,從而更可能具備這里說的兩種能力。

那麼,為什麼說演算法很難呢?這個問題只有兩種可能的原因:

演算法本身就很難。也就是說,演算法這個東西對於人類的大腦來說本身就是個困難的事兒。
講得太爛。
下面會說明,演算法之所以被絕大多數人認為很難,以上兩個原因兼具。

我們說演算法難的時候,有兩種情況:一種是學演算法難。第二種是設計演算法難。對於前者,大多數人(至少我當年如此)學習演算法幾乎是在背演算法,就跟背菜譜似的(「Cookbook」是深受廣大碼農喜愛的一類書),然而演算法和菜譜的區別在於,演算法包含的細節復雜度是菜譜的無數倍,演算法的問題描述千變萬化,邏輯過程百轉千回,往往看得人愁腸百結,而相較之下任何菜譜涉及到的基本元素也就那麼些(所以程序員肯定都具有成為好廚師的潛力:D)注意,即便你看了演算法的證明,某種程度上還是「背」(為什麼這么說,後面會詳述)。我自己遇到新演算法基本是會看證明的,但是發現沒多久還是會忘掉,這是死記硬背的標准症狀。如果你也啃過演算法書,我相信很大可能性你會有同感:為什麼當時明明懂了,但沒多久就忘掉了呢?為什麼當時明明非常理解其證明,但沒過多久想要自己去證明時卻發現怎麼都沒法補上證明中缺失的一環呢?

初中學習幾何證明的時候,你會不會傻到去背一個定理的證明?不會。你只會背結論。為什麼?一方面,因為證明過程包含大量的細節。另一方面,證明的過程環環相扣,往往只需要注意其中關鍵的一兩步,便能夠自行推導出來。演算法邏輯描述就好比定理,演算法的證明的過程就好比定理的證明過程。但不幸的是,與數學裡面大量簡潔的基本結論不同,演算法這個「結論」可不是那麼好背的,許多時候,演算法本身的邏輯就幾乎包含了與其證明過程等同的信息量,甚至演算法邏輯本身就是證明過程(隨便翻開一本經典的演算法書,看幾個經典的教科書演算法,你會發現演算法邏輯和演算法證明的聯系有多緊密)。於是我們又回到剛才那個問題:你會去背數學證明么?既然沒人會傻到去背整個證明,又為什麼要生硬地去背演算法呢?

那麼,不背就不背,去理解演算法的證明如何?理解了演算法的證明過程,便更有可能記住演算法的邏輯細節,理解記憶嘛。然而,仍然不幸的是,絕大多數演算法書在這方面做的實在糟糕,證明倒是給全了,邏輯也倒是挺嚴謹的,可是似乎沒有作者能真正還原演算法發明者本身如何得到演算法以及演算法證明的思維過程,按理說,證明的過程應該反映了這個思維過程,但是在下文關於霍夫曼編碼的例子中你會看到,其實飽受贊譽的CLRS和《Algorithms》不僅沒能還原這個過程,反而掩蓋了這個過程。

必須說明的是,沒有哪位作者是故意這樣做的,但任何人在講解一個自己已經理解了的東西的時候,往往會無意識地對自己的講解進行「線性化」,例如證明題,如果你回憶一下高中做平面幾何證明題的經歷,就會意識到,其實證明的過程是一個充滿了試錯,聯想,反推,特例,修改問題條件,窮舉等等一干「非線性」思維的,混亂不堪的過程,而並不像寫在課本上那樣——引理1,引理2,定理1,定理2,一口氣直到最終結論。這樣的證明過程也許容易理解,但絕對不容易記憶。過幾天你就會忘記其中一個或幾個引理,其中的一步或幾步關鍵的手法,然後當你想要回過頭來自己試著去證明的時候,就會發現卡在某個關鍵的地方,為什麼會這樣?因為證明當中並沒有告訴你為什麼作者當時會想到證明演算法需要那麼一個引理或手法,所以,雖說看完證明之後,對演算法這個結論而言你是知其所以然了,但對於演算法的證明過程你卻還沒知其所以然。在我們大腦的記憶系統當中,新的知識必須要和既有的知識建立聯系,才容易被回憶起來(《如何有效地學習與記憶》),聯系越多,越容易回憶,而一個天外飛仙似地引理,和我們既有的知識沒有半毛錢聯系,沒娘的孩子沒人疼,自然容易被遺忘。(為什麼還原思維過程如此困難呢?我曾經在知其所以然(一)里詳述)

正因為絕大多數演算法書上悲劇的演算法證明過程,很多人發現證明本身也不好記,於是寧可選擇直接記結論。當年我在數學系,考試會考證明過程,但似乎計算機系的考試考演算法證明過程就是荒謬的?作為「工程」性質的程序設計,似乎更注重使用和結果。但是如果是你需要在項目中自己設計一個演算法呢?這種時候最起碼需要做的就是證明演算法的正確性吧。我們面試的時候往往都會遇到一些演算法設計問題,我總是會讓應聘者去證明演算法的正確性,因為即便是一個「看上去」正確的演算法,真正需要證明起來往往發現並不是那麼容易。

所以說,絕大多數演算法書在作為培養演算法設計者的角度來說是失敗的,比數學教育更失敗。大多數人學完了初中平面幾何都會做證明題(數學書不會要求你記住幾何所有的定理),但很多人看完了一本演算法書還是一團漿糊,不會證明一些起碼的演算法,我們背了一坨又一坨結論,非但這些結論許多根本用不上,就連用上的那些也不會證明。為什麼會出現這樣的差異?因為數學教育的理想目的是為了讓你成為能夠發現新定理的科學家,而碼農系的演算法教育的目的卻更現實,是為了讓你成為能夠使用演算法做事情的工程師。然而,事情真的如此簡單么?如果真是這樣的話乾脆連演算法結論都不要背了,只要知道演算法做的是什麼事情,時空復雜度各是多少即可。

如果說以上提到的演算法難度(講解和記憶的難度)屬於Accidental Complexity的話,演算法的另一個難處便是Essential Complexity了:演算法設計。還是拿數學證明來類比(如果你看過《Introction to Algorithms:A Creative Approach》就知道演算法和數學證明是多麼類似。),與單單只需證明相比,設計演算法的難處在於,定理和證明都需要你去探索,尤其是前者——你需要去自行發現關鍵的那(幾)個定理,跟證明已知結論相比(已經確定知道結論是正確的了,你只需要用邏輯來連接結論和條件),這件事情的復雜度往往又難上一個數量級。

一個有趣的事實是,演算法的探索過程往往蘊含演算法的證明過程,理想的演算法書應該通過還原演算法的探索過程,從而讓讀者不僅能夠自行推導出證明過程,同時還能夠具備探索新演算法的能力。之所以這么說,皆因為我是個懶人,懶人總夢想學點東西能夠實現以下兩個目的:

一勞永逸:程序員都知道「一次編寫到處運行」的好處,多省事啊。學了就忘,忘了又得學,翻來覆去浪費生命。為什麼不能看了一遍就再也不會忘掉呢?到底是教的不好,還是學得不好?
事半功倍:事實上,程序員不僅講究一次編寫到處運行,更講究「一次編寫到處使用」(也就是俗稱的「復用」)。如果學一個演算法所得到的經驗可以到處使用,學一當十,推而廣之,時間的利用效率便會大大提高。究竟怎樣學習,才能夠使得經驗的外推(extrapolate)效率達到最大呢?
想要做到這兩點就必須盡量從知識樹的「根節點」入手,雖然這是一個美夢,例如數學界尋找「根節點」的美夢由來已久(《跟波利亞學解題》的「一點歷史」小節),但哥德爾一個證明就讓美夢成了泡影(《永恆的金色對角線》));但是,這並不阻止我們去尋找更高層的節點——更具普適性的解題原則和方法。所以,理想的演算法書或者演算法講解應該是從最具一般性的思維法則開始,順理成章地推導出演算法,這個過程應該盡量還原一個」普通人「思考的過程,而不是讓人看了之後覺得」這怎麼可能想到呢?

以本文上篇提到的霍夫曼編碼為例,第一遍看霍夫曼編碼的時候是在本科,只看了演算法描述,覺得挺直觀的,過了兩年,忘了,因為不知道為什麼要把兩個節點的頻率加在一起看做單個節點——一件事情不知道「為什麼」就會記不牢,知道了「為什麼」的話便給這件事情提供了必然性。不知道「為什麼」這件事情便可此可彼,我們的大腦對於可此可彼的事情經常會弄混,它更容易記住有理有據的事情(從資訊理論的角度來說,一件必然的事情概率為1,信息量為0,而一件可此可彼的事情信息量則是大於0的)。第二遍看是在工作之後,終於知道要看證明了,拿出著名的《Algorithms》來看,邊看邊點頭,覺得講得真好,一看就理解了為什麼要那樣來構造最優編碼樹。可是沒多久,又給忘了!這次忘了倒不是忘了要把兩個節點的頻率加起來算一個,而是忘了為什麼要這么做,因為當時沒有弄清霍夫曼為什麼能夠想到為什麼應該那樣來構造最優編碼樹。結果只知其一不知其二。

必須說明的是,如果只關心演算法的結論(即演算法邏輯),那麼理解演算法的證明就夠了,光背演算法邏輯難記住,理解了證明會容易記憶得多。但如果也想不忘演算法的證明,那麼不僅要理解證明,還要理解證明背後的思維,也就是為什麼背後的為什麼。後者一般很難在書和資料上找到,唯有自己多加揣摩。為什麼要費這個神?只要不會忘記結論不就結了嗎?取決於你想做什麼,如果你想真正弄清演算法設計背後的思想,不去揣摩演算法原作者是怎麼想出來的是不行的。

3. 我目前在自學演算法,但是我感覺很吃力啊。有時候一個稍微復雜的演算法,想很久都不能明白。希望前輩們給點建

什麼要求,但是,我認為,如果編程要學的很深入,要編大程序或大規模編程,做專業的程序設計員,那好的演算法就十分重要了,好演算法可以把一個程序的速度提升很多。上機覺得吃力,是對概念和語句用法還是不是很清楚吧。如果是對語句不熟練,感到吃力,那就要多看書,看例題,看別人為什麼是這樣寫的,這樣寫有什麼好處?這樣,多總結,再多練習,再上機的話,感覺應該會好很多的。
其實,很多演算法,都在一些優秀的例題代碼中出現,多總結觀察就好了。
ps:感覺吃力說明基本功不夠扎實,不一定演算法不好的問題。一開始學編程,只要編出來就OK了,等大部分概念和知識點掌握了,再優化你從前程序。還有,對於一道題,在你學程序的不同階段里,你會編出不同代碼,因為在學習的過程中,你掌握了更多的語句,也就掌握了更多的方法去解決一道題。
祝你學習順利。^_^
另外,團IDC網上有許多產品團購,便宜有口碑

4. 演算法那麼難理解啊

認真思考,理解每個語句的意思,看不懂的、有問題的就去問老師,還有要多實踐、多練習,多思考幾遍就會熟練的。

5. c語言有些演算法理解不了怎麼辦好苦惱。

什麼演算法,慢慢的就會理解的,要不就發過來讓大夥看看,最好還是自己網路,更全面些,要麼一般的解答很不全面,要麼就是粘貼過來的,最好還是自己網路,你不網路自己怎麼會理解呢,?不然輕易理解的演算法就不能叫做演算法來讓大家學習了,所以我的建議是 「最好還是自己網路」

6. 學編程,什麼叫演算法 為什麼很多人說演算法很難

其實說白了,演算法就是解決某種問題的方式,但也分好的演算法和差的演算法,而學習書本上的知識目的就是為了提升自己的思維方式,借鑒更多好的演算法,因為好的演算法可以提升程序的性能,提高開發效率,就拿最簡單的例子,玩猜數字游戲,1-100裡面隨便選一個數字,然後讓你去猜它是多少,別人會告訴你這個數字大了還是小了,最直接的方式就是從1一直猜到100,但是也有更簡便的方式:就是類似二分法的方式從50開始猜,如果大了就猜1-50中的25,如果小了猜50-100中的75,以此類推,第一種從1-100猜數字是演算法,第二種二分法的方式也是演算法,只是第二種更好.........還有從1加到100,直接方式1+2+3....一個一個的加,另一種方式(1+100)*50,這個就是著名的高斯演算法。

7. 請問各位我最近學習了一些演算法,看源代碼的時候還是感覺很難理解,望各位支點招,謝謝。

你可以先把這些代碼照抄10遍以上加深印象
這是很枯草的 但是沒辦法
每一行代碼都是經驗的積累
多練 多打肯定沒錯 你有了思想 不代表你有了實際操作的經驗
所以你還是需要多練 理論結合實際 這樣進步才快 不要偷懶哦

每一個零基礎的人士 剛學都會有這種感覺
每個人都會經歷這樣一個過程
起步肯定是艱辛的 但是過了這道坎
只要入門了 接下來的路就會越來越有趣的

8. 演算法該怎麼學感覺好難

很多人都會說"學一樣東西難",一開始我也覺得很大程度是因為每個人的智力水平等等不可改變的因素. 但是後來我發現,有一個東西也很能決定一個人是否會覺得一樣東西難學,那就是理解方式.

一件事物通過不同的途徑讓一個人理解效果差異是很大的.就比如說數學裡面教你一個圓,有的人看到一個圓就能很快明白什麼是圓,有的人卻非得看到x^2+y^2 = r^2這種式子才有感覺,甚至有的人需要"到定點距離為定長的點集"這種描述才能理解. 那這個不一定是說誰的智力水平更高,而是因為他們對不同形式事物的敏感程度不同.


回到演算法上來.演算法本質是一種數學.他是抽象的操作集合.(看這么說你可能會覺得不知所雲,但是如果我說他只是一種解決問題的辦法可能就好理解). 所以很多書,論文,或者很多老師教的都是一種數學描述的演算法,這樣子的演算法就我個人而言相當難理解,看了就想到代數高數什麼的.. 但是如果找一個圖文並茂的解釋,或者找個人一步一步把一個演算法給你我比劃一下,我立刻就能理解. 說白了,就是你一定要找很多很多不同的角度來嘗試接受一種東西,你一定可以找到一種你相當敏感的角度,用這個角度學習你就會游刃有餘. 智力因素並沒有太大影響的.


具體點說,你可以試試這幾種不同的角度.

  1. 直接看數學形式的演算法.我個人最無法接受的形式,但是有人很喜歡..例子就是演算法導論上面那種描述.

  2. 聽一般語言描述,最理想是找一個明白的人,給你用通俗語言講講原理.這個不錯,很多我是這么理解的

  3. 圖形理解,叫理解的人給你畫插圖,分布圖,結構圖等等,來分解一個演算法,找到他的思路.說到圖,有一個人的博客這方面做得很好:matrix67.

  4. 程序理解.找到一種演算法的實現程序,對著程序理解,可以嘗試分布運行,觀察一下變數的變化,這樣來理解演算法.

  5. 實在太難的演算法,可以邊寫邊改來理解.當時我學習插頭dp的時候就是這樣,不論怎麼總是一知半解,最後硬著頭皮寫了一遍,改了很久,但是改過了的時候,也就真的明白了是怎麼回事了.


也許還有別的什麼辦法,因為人對事物的接受角度實在是太多了.多想想你平時學習什麼比較容易,找出你最敏感的理解方式就行了.


有感而發說的一些東西,不一定都是正確的,只供參考,歡迎指正.

熱點內容
哮喘病人為什麼晚上會喘 發布:2025-05-25 17:11:08 瀏覽:384
為什麼美團能在短時間內發展起來 發布:2025-05-25 17:09:41 瀏覽:868
為什麼找不到適合自己的生意 發布:2025-05-25 17:06:17 瀏覽:272
為什麼電腦主機是兩個電源按鍵 發布:2025-05-25 17:04:54 瀏覽:787
為什麼手機顯示歸屬地不一樣 發布:2025-05-25 17:03:11 瀏覽:145
冬天能用散餌為什麼不好用 發布:2025-05-25 17:01:48 瀏覽:351
ios13為什麼軟體還是很大 發布:2025-05-25 17:00:51 瀏覽:741
小米手機流量打開了為什麼不能用 發布:2025-05-25 16:57:40 瀏覽:608
為什麼休息什麼時間 發布:2025-05-25 16:56:50 瀏覽:689
小米10為什麼插耳機沒聲音 發布:2025-05-25 16:55:28 瀏覽:817