Ⅰ 演算法怎麼就這么難
廣大碼農同學們大多都有個共識,認為演算法是個硬骨頭,很難啃,悲劇的是啃完了還未必有用——除了面試的時候。實際工程中一般都是用現成的模塊,一般只需了解演算法的目的和時空復雜度即可。
不過話說回來,面試的時候面演算法,包括面項目中幾乎不大可能用到的演算法,其實並不能說是毫無道理的。演算法往往是對學習和理解能力的一塊試金石,難的都能掌握,往往容易的事情不在話下。志於高者得於中。反之則不成立。另一方面,雖說教科書演算法大多數都是那些即便用到也是直接拿模塊用的,但不幸的是,我們這群搬磚頭的有時候還非得做些發明家的事情:要麼是得把演算法當白盒加以改進以滿足手頭的特定需求;要麼乾脆就是要發明輪子。所以,雖說面試的演算法本身未必用得到,但熟悉各種演算法的人通常更可能熟悉演算法的思想,從而更可能具備這里說的兩種能力。
那麼,為什麼說演算法很難呢?這個問題只有兩種可能的原因:
演算法本身就很難。也就是說,演算法這個東西對於人類的大腦來說本身就是個困難的事兒。
講得太爛。
下面會說明,演算法之所以被絕大多數人認為很難,以上兩個原因兼具。
我們說演算法難的時候,有兩種情況:一種是學演算法難。第二種是設計演算法難。對於前者,大多數人(至少我當年如此)學習演算法幾乎是在背演算法,就跟背菜譜似的(「Cookbook」是深受廣大碼農喜愛的一類書),然而演算法和菜譜的區別在於,演算法包含的細節復雜度是菜譜的無數倍,演算法的問題描述千變萬化,邏輯過程百轉千回,往往看得人愁腸百結,而相較之下任何菜譜涉及到的基本元素也就那麼些(所以程序員肯定都具有成為好廚師的潛力:D)注意,即便你看了演算法的證明,某種程度上還是「背」(為什麼這么說,後面會詳述)。我自己遇到新演算法基本是會看證明的,但是發現沒多久還是會忘掉,這是死記硬背的標准症狀。如果你也啃過演算法書,我相信很大可能性你會有同感:為什麼當時明明懂了,但沒多久就忘掉了呢?為什麼當時明明非常理解其證明,但沒過多久想要自己去證明時卻發現怎麼都沒法補上證明中缺失的一環呢?
初中學習幾何證明的時候,你會不會傻到去背一個定理的證明?不會。你只會背結論。為什麼?一方面,因為證明過程包含大量的細節。另一方面,證明的過程環環相扣,往往只需要注意其中關鍵的一兩步,便能夠自行推導出來。演算法邏輯描述就好比定理,演算法的證明的過程就好比定理的證明過程。但不幸的是,與數學裡面大量簡潔的基本結論不同,演算法這個「結論」可不是那麼好背的,許多時候,演算法本身的邏輯就幾乎包含了與其證明過程等同的信息量,甚至演算法邏輯本身就是證明過程(隨便翻開一本經典的演算法書,看幾個經典的教科書演算法,你會發現演算法邏輯和演算法證明的聯系有多緊密)。於是我們又回到剛才那個問題:你會去背數學證明么?既然沒人會傻到去背整個證明,又為什麼要生硬地去背演算法呢?
那麼,不背就不背,去理解演算法的證明如何?理解了演算法的證明過程,便更有可能記住演算法的邏輯細節,理解記憶嘛。然而,仍然不幸的是,絕大多數演算法書在這方面做的實在糟糕,證明倒是給全了,邏輯也倒是挺嚴謹的,可是似乎沒有作者能真正還原演算法發明者本身如何得到演算法以及演算法證明的思維過程,按理說,證明的過程應該反映了這個思維過程,但是在下文關於霍夫曼編碼的例子中你會看到,其實飽受贊譽的CLRS和《Algorithms》不僅沒能還原這個過程,反而掩蓋了這個過程。
必須說明的是,沒有哪位作者是故意這樣做的,但任何人在講解一個自己已經理解了的東西的時候,往往會無意識地對自己的講解進行「線性化」,例如證明題,如果你回憶一下高中做平面幾何證明題的經歷,就會意識到,其實證明的過程是一個充滿了試錯,聯想,反推,特例,修改問題條件,窮舉等等一干「非線性」思維的,混亂不堪的過程,而並不像寫在課本上那樣——引理1,引理2,定理1,定理2,一口氣直到最終結論。這樣的證明過程也許容易理解,但絕對不容易記憶。過幾天你就會忘記其中一個或幾個引理,其中的一步或幾步關鍵的手法,然後當你想要回過頭來自己試著去證明的時候,就會發現卡在某個關鍵的地方,為什麼會這樣?因為證明當中並沒有告訴你為什麼作者當時會想到證明演算法需要那麼一個引理或手法,所以,雖說看完證明之後,對演算法這個結論而言你是知其所以然了,但對於演算法的證明過程你卻還沒知其所以然。在我們大腦的記憶系統當中,新的知識必須要和既有的知識建立聯系,才容易被回憶起來(《如何有效地學習與記憶》),聯系越多,越容易回憶,而一個天外飛仙似地引理,和我們既有的知識沒有半毛錢聯系,沒娘的孩子沒人疼,自然容易被遺忘。(為什麼還原思維過程如此困難呢?我曾經在知其所以然(一)里詳述)
正因為絕大多數演算法書上悲劇的演算法證明過程,很多人發現證明本身也不好記,於是寧可選擇直接記結論。當年我在數學系,考試會考證明過程,但似乎計算機系的考試考演算法證明過程就是荒謬的?作為「工程」性質的程序設計,似乎更注重使用和結果。但是如果是你需要在項目中自己設計一個演算法呢?這種時候最起碼需要做的就是證明演算法的正確性吧。我們面試的時候往往都會遇到一些演算法設計問題,我總是會讓應聘者去證明演算法的正確性,因為即便是一個「看上去」正確的演算法,真正需要證明起來往往發現並不是那麼容易。
所以說,絕大多數演算法書在作為培養演算法設計者的角度來說是失敗的,比數學教育更失敗。大多數人學完了初中平面幾何都會做證明題(數學書不會要求你記住幾何所有的定理),但很多人看完了一本演算法書還是一團漿糊,不會證明一些起碼的演算法,我們背了一坨又一坨結論,非但這些結論許多根本用不上,就連用上的那些也不會證明。為什麼會出現這樣的差異?因為數學教育的理想目的是為了讓你成為能夠發現新定理的科學家,而碼農系的演算法教育的目的卻更現實,是為了讓你成為能夠使用演算法做事情的工程師。然而,事情真的如此簡單么?如果真是這樣的話乾脆連演算法結論都不要背了,只要知道演算法做的是什麼事情,時空復雜度各是多少即可。
如果說以上提到的演算法難度(講解和記憶的難度)屬於Accidental Complexity的話,演算法的另一個難處便是Essential Complexity了:演算法設計。還是拿數學證明來類比(如果你看過《Introction to Algorithms:A Creative Approach》就知道演算法和數學證明是多麼類似。),與單單只需證明相比,設計演算法的難處在於,定理和證明都需要你去探索,尤其是前者——你需要去自行發現關鍵的那(幾)個定理,跟證明已知結論相比(已經確定知道結論是正確的了,你只需要用邏輯來連接結論和條件),這件事情的復雜度往往又難上一個數量級。
一個有趣的事實是,演算法的探索過程往往蘊含演算法的證明過程,理想的演算法書應該通過還原演算法的探索過程,從而讓讀者不僅能夠自行推導出證明過程,同時還能夠具備探索新演算法的能力。之所以這么說,皆因為我是個懶人,懶人總夢想學點東西能夠實現以下兩個目的:
一勞永逸:程序員都知道「一次編寫到處運行」的好處,多省事啊。學了就忘,忘了又得學,翻來覆去浪費生命。為什麼不能看了一遍就再也不會忘掉呢?到底是教的不好,還是學得不好?
事半功倍:事實上,程序員不僅講究一次編寫到處運行,更講究「一次編寫到處使用」(也就是俗稱的「復用」)。如果學一個演算法所得到的經驗可以到處使用,學一當十,推而廣之,時間的利用效率便會大大提高。究竟怎樣學習,才能夠使得經驗的外推(extrapolate)效率達到最大呢?
想要做到這兩點就必須盡量從知識樹的「根節點」入手,雖然這是一個美夢,例如數學界尋找「根節點」的美夢由來已久(《跟波利亞學解題》的「一點歷史」小節),但哥德爾一個證明就讓美夢成了泡影(《永恆的金色對角線》));但是,這並不阻止我們去尋找更高層的節點——更具普適性的解題原則和方法。所以,理想的演算法書或者演算法講解應該是從最具一般性的思維法則開始,順理成章地推導出演算法,這個過程應該盡量還原一個」普通人「思考的過程,而不是讓人看了之後覺得」這怎麼可能想到呢?
以本文上篇提到的霍夫曼編碼為例,第一遍看霍夫曼編碼的時候是在本科,只看了演算法描述,覺得挺直觀的,過了兩年,忘了,因為不知道為什麼要把兩個節點的頻率加在一起看做單個節點——一件事情不知道「為什麼」就會記不牢,知道了「為什麼」的話便給這件事情提供了必然性。不知道「為什麼」這件事情便可此可彼,我們的大腦對於可此可彼的事情經常會弄混,它更容易記住有理有據的事情(從資訊理論的角度來說,一件必然的事情概率為1,信息量為0,而一件可此可彼的事情信息量則是大於0的)。第二遍看是在工作之後,終於知道要看證明了,拿出著名的《Algorithms》來看,邊看邊點頭,覺得講得真好,一看就理解了為什麼要那樣來構造最優編碼樹。可是沒多久,又給忘了!這次忘了倒不是忘了要把兩個節點的頻率加起來算一個,而是忘了為什麼要這么做,因為當時沒有弄清霍夫曼為什麼能夠想到為什麼應該那樣來構造最優編碼樹。結果只知其一不知其二。
必須說明的是,如果只關心演算法的結論(即演算法邏輯),那麼理解演算法的證明就夠了,光背演算法邏輯難記住,理解了證明會容易記憶得多。但如果也想不忘演算法的證明,那麼不僅要理解證明,還要理解證明背後的思維,也就是為什麼背後的為什麼。後者一般很難在書和資料上找到,唯有自己多加揣摩。為什麼要費這個神?只要不會忘記結論不就結了嗎?取決於你想做什麼,如果你想真正弄清演算法設計背後的思想,不去揣摩演算法原作者是怎麼想出來的是不行的。
Ⅱ 演算法難學么
真正的演算法學習起來,存在一定的難度的,堅持很重要,畢竟裡面的東西的學習,需要耐心去看不能只是三分鍾的熱度基本學不會,畢竟演算法的學習需要注意力高度集中,不停的燒腦學習。不適合學習一段時間就輕易放棄的人,所以沒點毅力根本就學不好演算法,更加談不上學習編程了。
以上資料僅供參考。
Ⅲ c語言高難度演算法,菜鳥勿進! ^_^
//我做出來了。
//輸入:A1,A3,A2,A8,A7,A6,A5,A4
//輸出:A1,A2,A3,A4,A5,A6,A7,A8
//只是對輸入的字串長度限制在100以內。
#include "stdio.h"
int main( )
{
char str1[100];
//輸入字元串
printf("請輸入字元串:");
scanf("%s",str1);
//對字元串分組
char str[50][3];
char *p=str1;
int i=0,j=0;
for(;*p!='\0';p++)
{
if(*p!=',')
{
str[i][j]=*p;
j++;
}
else
{
str[i][j]='\0';
i++;
j=0;
}
}
str[i][j]='\0';
i++;
j=0;
//對字串排序
for(j=0;j<i;j++)
for(int k=j+1;k<i;k++)
{
if(str[j][1]>str[k][1])
{
char temp;
temp=str[j][0];
str[j][0]=str[k][0];
str[k][0]=temp;
temp=str[j][1];
str[j][1]=str[k][1];
str[k][1]=temp;
}
}
//復制排序好的字串
p=str1;
for(j=0;j<i;j++)
{
*p=str[j][0];
p++;
*p=str[j][1];
p++;
if(j<i-1)
{
*p=',';
p++;
}
}
*p='\0';
//輸出排序好的字串
printf("排序後的符串:%s",str1);
printf("\n");
}
Ⅳ 學演算法很難么
這個不好說的,就看你自己的學習能力和接受能力了,你可以先找點演算法的書籍看下,看看難度系數怎麼樣的。反正對於我來說是比較難的,當年學的不是很好。
Ⅳ 一種演算法用硬體實現的難易程度主要看什麼或者說用什麼來衡量
我個人覺得要看這種演算法和硬體的匹配度
舉個簡單的例子,cpu內部有做好的加法器有現成的加法指令,所以完成加法就很簡單,也很快,如果你的演算法有很多除法,但CPU內部又沒有除法結構也沒有相關指令,你完成除法這個演算法就需要自己通過其他方式來完成,這就是難易度的體現。
Ⅵ 決策樹演算法和神經網路演算法哪個難
不是很清楚題主所說的難具體指什麼
如果題主指應用演算法解決實際問題的話 決策樹要簡單一些 有很多封裝的很好的decision tree的包,比如CART,C4.5等等 而神經網路(NN)一般有大量參數需要手工設置和調節
如果題主指演算法推導的難度的話 兩個差不多吧 決策樹的分裂方法可能稍微簡單一下 NN的話用BP或者SGD的話都需要用chain rule求導
Ⅶ 演算法分析難不難
演算法分析設計是很難的。要把離散數學、數據結構、編譯原理學好,其實編譯原理更難。
Ⅷ 轉帖:演算法好學嗎——《大話數據結構》讀者書評
om/?p=739作者:陳鋼摸著鍵盤寫這篇東西的直接動力是給程傑剛剛出版的大作《大話數據結構》寫個書評,外加利用我這微乎其微的影響力做做廣告怎麼說程傑同學也送了我一本親筆簽名的繁體版《大話數據結構》。不過,今天早上看到了劉未鵬的新文章,知其所以然(三):為什麼演算法這么難?,我覺得光寫書評不太爽,寫點我學演算法的失敗經歷吧,順帶說說程傑同學的這本新書。 說實話,本文的標題是個偽命題。演算法是否好學,或者說是否容易學,完全取決於你的學習目標,是要應付下個月的考試,還是准備考個研究生,或者是想搞定二三流公司的筆試,還是想去微軟當科學家當然,不排除有人的目標是圖靈獎。不動腦子都能知道,只是應付考試的學習應該是難度最低的,真正在復雜的業務流程中合理的設計和應用高效的演算法的難度無疑要高出一截,至於圖靈獎我也不知道,那玩意太遙遠。 目標的不同導致了所需的學習資料是完全不同的,《大話數據結構》的封底是這樣描述它的目標讀者的:《大話數據結構》適合學過一門編程語言的如下讀者: 在讀的大中專計算機專業學生; 想轉行做開發的非科班人員; 想考計算機專業研究生的應屆或在職人員; 工作後想重溫數據結構和演算法的程序員; 顯然,從目標讀者就能看出,這本書不是給高手看的。我曾經扮演過其中的一種角色,想考計算機專業研究生的應屆或在職人員,不過我那時候讀的是一本經典的教材,嚴蔚敏老師的《數據結構》(其實在《大話》前言中也提及了這本書)。因為所學的專業跟計算機搭界不多,所以在考研前所有的計算機知識來自於三門包羅萬象卻連點到即止就算不上的課程:計算機導論、計算機軟體設計、計算機硬體設計。當時的學習方法就是劉未鵬說的背,不管演算法和各種數據結構的來龍去脈,也無論能否理解,一律背下來。反正當時的目標就是考研究生。 但我也發現,本為考研究生而短期惡補的知識,應付一般的企業筆試和面試也勉強夠了。考研復習其實挺枯燥的,每天重復幾乎類似的生活。有天同學說,傳說中的華為來學校宣講。為了調劑一下生活,捏著一頁紙的簡歷就跑去應聘軟體開發職位。一輪筆試,幾輪面試下來,憑著我兩個月惡補的那點數據結構知識,我竟然全部通過了。體驗完簽約儀式注意,只是體驗了一下,然後回到教室繼續備考。 最後,考研的專業課也得了個還不錯的成績。從這方面看,演算法、數據結構之類的東西學起來似乎並不難,短時間抱著死板的教材就能應付考試,應付企業的筆試面試。如果能讀讀《大話》這樣通俗易懂的讀物,達到這樣的目的應該是更加容易。我當時真正的水平怎麼樣?啥都不會,動態規劃都寫不完整,分治法之類的東西就更不懂了。NP-complete理論?沒聽說過。光是背了幾篇經典小說的人,看過小說背景介紹的人是寫不出什麼好東西的。必須要了解別人作品的前前後後方方面面,自己不停地寫,不停地想,才有可能真的寫出好東西。演算法也是如此,弄清楚每個數據結構、演算法的每個細節的緣由,才能設計出自己的好演算法。但市面上能像劉未鵬的知其所以然(三):為什麼演算法這么難?這樣解析演算法的書是沒有的。即使是劉未鵬寫了幾篇,要等他攢出一本完整的書,也需要漫長的等待。而且全書每個演算法的解析是否都能到這個水平也是個疑問。 但如果搞計算機的人都停留在《大話》所要達到的水平,那無疑是一種悲哀。我學演算法的經歷之所以失敗,正是因為如此。為了考試而啃完嚴蔚敏老師的《數據結構》和一兩本考試參考書之後,我再也沒有讀完一本演算法的書,也沒有自己寫過稍有難度的演算法。所以,水平也就一直停留在看看文檔,調調函數的水平上。 希望有人能以《大話》為起點,而不是以讀完此書為終點;也期望程傑兄能創作出更高水平的佳作。 陳鋼同學是我的朋友,在我寫作時給予了我很多幫助。此評論寫得相當客觀,並沒有誇大地說好話,而是強調了《大話數據結構》僅僅只是數據結構與演算法學習的起步而已。我轉帖出來,也是希望讀者可以了解,演算法要學好,可真不是幾日之功。我們都需要不斷努力!
Ⅸ 計算機演算法有多難
不算太難,好好學就能學會,就是需要多復習,不然就忘了
Ⅹ 閱讀、電影和音樂的推薦演算法,哪一個更難做
「閱讀、電影和音樂的推薦演算法,哪一個更難做?為什麼?」關於這一問題,小編從諸多網友的回復中為你篩選了最用心、最高贊的回答!快來看看吧~
來看看網名為「幸運的ZLT0502」的網友是怎麼說的:
電影---音樂----閱讀!從我的經驗來看,閱讀是最難做到的,其次是音樂,最簡單的就是電影。當然,是在有很多數據的前提下。從幾個領域的特點來看:1.電影的item數量相對較少,好的電影有很長的生命周期,加上電影社區的用戶行為,視頻網站或預訂網站,都很好獲得,所以特別適合合作過濾。即使這不是一部大熱門電影,你也可以根據導演、類型、明星等製作內容。這些都是結構化的信息,所以沒有難度。音樂的item比電影要多一些,生命周期也非常不同,但它也可以用於基於用戶行為的協同過濾。該演算法如何表達和更新用戶的興趣?如何根據興趣標簽計算推薦結果?至少我沒有看到特別成功的推薦閱讀應用程序。演算法上,都各有難度,但閱讀類的,由於分類太多,在演算法上自然要更加復雜。
來看看網名為「派網友」的網友是怎麼說的:
個人認為無論是基於用戶行為(協同過濾),還是基於內容相似度的推薦演算法,難度從高到底都依次是:音樂-閱讀-電影。
對於ID為「樓船吹笛雨瀟瀟」網友的精彩回答,大家紛紛點贊支持,他是這么說的:
我覺得是各有所難,並不能說哪個難,哪個容易。推薦的成功率:公共決策對推薦的影響:判斷價值的建議:三者各有難度,但是個人在長期的習慣中可以對其中一種或者多種情景中加以選擇和實踐,但這也不是一蹴而就的事情,慢慢來吧。
你贊同哪位網友的觀點呢?