那些年啊,那些事 乙個程式設計師的奮鬥史 51

2021-08-31 15:57:25 字數 3054 閱讀 8238

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!

本以為英漢字典的程式已經沒有什麼大問題了,沒想到今天段伏櫪想查乙個單詞,卻發現事情根本就不是自己所料想的那麼順利:單詞的查詢速度太慢!這就奇怪了,之前為什麼沒有發現呢?說起來也讓人啼笑皆非。之前之所以沒發現這問題,是因為測試的時候,輸入的單詞都是以「a」開頭的,而今天碰巧要查詢的單詞,卻是以「x」開頭!就這麼乙個小差別,導致搜尋所花的時間居然要比「a」開頭的字母多兩分鐘!

這也是沒有辦法的事,因為段伏櫪的查詢演算法,是最最最原始的:從「a」開始,乙個乙個進行對比,看看哪個單詞最符合。換句話來說,如果單詞不存在,或是位於字型檔的後半部分,那麼搜尋所花費的時間絕對是讓人咋舌的。其實一開始寫查詢演算法的時候,段伏櫪也擔心過這個問題,但沒想到的是,當自己將程式寫完之後,居然把這碼子事給忘了;並且測試的時候,都是以「a」開頭,那搜尋的速度自然是超快,更讓段伏櫪完全淡忘了這問題。

怎麼辦?這樣的效率,擱誰身上都受不了啊。總不能查乙個「a」開頭的單詞不到十秒鐘,但找個「z」開頭的,撒了泡尿回來泡了杯茶後還沒結束吧?沒轍,修改演算法唄。演算法?段伏櫪一想到這兩個詞,腦袋就變成兩個大。對於高考150分滿分只考了60分,看到傅利葉變化就兩眼冒金星的段伏櫪來說,讓他去折騰演算法無異於慢性折磨。

這帶來乙個很有意思的話題:程式設計師究竟要不要研究演算法?其實這在業界中也是一直爭論不休。正方的意見是,不懂得演算法,那麼就不能更好的理解計算機,寫出的軟體效率就會非常低,因為程式就是**+演算法的結合;而反方的意見呢,無非就是說現在有很多演算法庫,可以直接拿來就用,根本就不必要去深究,不必要再花費心思去研究輪子如何工作。關於是否需要專研演算法的問題,段伏櫪沒有絲毫的猶豫,義不容辭直接選擇反方,這倒不是因為他多麼的**遠矚,或是有什麼堅定的信仰之類,純粹是因為他先天不足:從小對數學就不感冒,看著這變化來變化去的公式就頭暈,這模樣還怎能研究演算法?

盲目崇拜,或是盲目鄙視演算法,這兩種態度都是不可取的,關鍵是看自己用演算法來做什麼。就像一輛法拉利跑車,估計沒有人會說它差,開著它在路上狂奔,估計是乙個非常愜意的享受。可是如果任務是要從大陸到日本,需要越過海洋,那麼這法拉利的價值估計還不如一艘破船。可是這時候,你能說法拉利一無是處嗎?一無是處的是使用者,因為他沒有將法拉利用在最恰當的場合。演算法也是如此,它是否有用,能發揮多大的作用,關鍵是看用它的人,看用它的場合。

根據對演算法的掌握程度,大體上可以將程式設計師分為三類:第一種是對演算法非常精通的,第二種是知道有哪麼些演算法概念知道相應的演算法庫該如何使用的,最後一種是對演算法一竅不通甚至連演算法庫都不知道的。這三種人之中,第一種是神一樣的人物,適合於從事提公升產品競爭力的工作;第二種便是大多數程式設計師所處的範圍,適合產品的應用開發;最後一種嘛,便是菜鳥級別的,遇到和演算法有關的問題只能撞得頭破血流。很不幸,段伏櫪就屬於最後一種。

當然,現在是菜鳥,並不代表一無是處,高手嘛,不也是從雛鳥開始的?俺就不信,那些演算法高手,在娘胎的時候就懂得傅利葉變換?只聽過用柔和的**來進行胎教的,可還真沒聽過念數學公式來進行的。絕對不向困難低頭,是段伏櫪一貫堅持的信念,也是一直能夠進步的原因之一。不就個演算法嘛?這還難得了俺?拿本演算法書看看不就好了。確實是拿本演算法書看看,很多不明白的東西都清晰了,可這也要能看得懂啊。沒翻幾頁,段伏櫪就翻白眼了:這是哪門子的邪門歪道?中文每個文字都能看懂,字母才26個字母,可組合起來,咋就跟天書一樣了呢?還有還有,這演算法的評判標準也太麻煩了吧?不同情況下的表現形式還不同啊?這不折騰老子嗎?

算了,管它那麼多,還什麼演算法優劣呢!以自己現在的水平,等研究出來,估計到時候公司在不在還不好說。不用去想那麼複雜了,那是不是自己這個水平檔次的人所能幹的事。自己只要演算法比以前的那個逐個逐個比較要快,每個單詞查詢的時間差不多就行了。

只是,要選哪個呢?這些英文在的排列是按順序的,如果以二分法的話,直覺上應該可以快很多;並且這二分法的特性,對於已經排序的單詞來說,查詢的頻度應該相差無幾。好,那就是它了!就是二分法!其實,如果不選二分法,那也沒有其它的選擇了,因為對於段伏櫪來說,只有這二分法他還能看得懂,還能夠比較容易地轉化為**。

因為之前的單詞搜尋是在dll檔案中,所以要更改演算法的話,只需要更改dll的原始檔即可。不僅如此,之前的演算法暴露的是乙個函式介面,現在只需要更改函式體的內容,而不必重新書寫**。雖然當時段伏櫪寫程式的時候,並沒有考慮到後續可能需要更改演算法的狀況,但憑藉著直覺,覺得有一些東西應該以函式形式封裝起來,沒想到這給後續的修改省去了不少麻煩。

英文單詞是以陣列來儲存的,如果要更改演算法,只需要增加三個指標,分別指向開頭,末尾,和中間的序號,然後再和所要查詢的單詞做比較即可。演算法轉換為**,並不是很困難的事,但有一些小細節卻需要注意,所以段伏櫪花了整整一天時間,才讓這演算法正常工作。過程是曲折的,但結果是喜人的,這麼一更改之後,搜尋後半部單詞的速度確實比之前要快很多,簡直完全是天壤之別。看著改善後的英漢字典程式,段伏櫪不禁手舞足蹈:自己終於也能寫字典程式了!當年老章所做的事情,自己也能做了!更為重要的是,一向對演算法白痴的自己,居然還懂得寫了個二分法演算法!還有什麼能比這更高興的嗎?

只不過當時的段伏櫪不知道,如果要寫像他現在這種檔次要求的字典程式,完全可以不用這麼麻煩:不用去考慮如何儲存字典資料,不用考慮如何根據返回值查詢注釋,不用花費心思去考慮查詢演算法——因為這一切,只需要使用stl的multimap即可解決。multimap的結構很簡單,是以key-value的方式儲存。如果應用到英漢字典,那麼key儲存的就是英文單詞,而value自然就是注釋了。一旦需要查詢的時候,那也是非常簡單,直接呼叫find函式即可。那麼這stl的效率如何呢?只能說,stl的演算法可能並不是最佳的,但絕對不是最差的,不過對於段伏櫪的應用而言,完全是綽綽有餘。

雖然段伏櫪在《c++ primer》見過multimap的身影,但該書對於應用卻惜字如金,並沒有很好詮釋用法。所以段伏櫪對此的印象也不是很深,在編寫程式的時候自然沒有想到使用該容器。如果在此之前段伏櫪看過《c++ 標準程式庫》的話,可能情形截然不同。該書從最基礎開始,給讀者介紹了stl的使用,特別是其中的一章,更是以字典為例來進行講解如何使用multimap,恰好和段伏櫪的程式要求不謀而合。

這不能不說,多看書,對於程式設計師而言,是多麼重要。也許看的時候確實一竅不通,但只要你對此有了那麼點印象,知道有那麼一回事,說不定就這麼乙個靈感,會讓以後的工作省掉很多的麻煩。           

給我老師的人工智慧教程打call!

《那些年啊,那些事 乙個程式設計師的奮鬥史》 01

段伏櫪,乙個瘦小,矮小,根本和 帥 這個字粘不上任何關係的普通人。名字的 在於其多讀了幾年書的老爹,總抱著有一天要出書出名乃至於名流千古的美好理想,但可惜現實總是給予他無情的而又現實的打擊,於是就將理想寄望於自己的兒子,起了個 伏櫪 的名,寓意為 老驥伏櫪,志在千里 表達自己不到黃河不死心的良好的願...

《那些年啊,那些事 乙個程式設計師的奮鬥史》 01

段伏櫪,乙個瘦小,矮小,根本和 帥 這個字粘不上任何關係的普通人。名字的 在於其多讀了幾年書的老爹,總抱著有一天要出書出名乃至於名流千古的美好理想,但可惜現實總是給予他無情的而又現實的打擊,於是就將理想寄望於自己的兒子,起了個 伏櫪 的名,寓意為 老驥伏櫪,志在千里 表達自己不到黃河不死心的良好的願...

《那些年啊,那些事 乙個程式設計師的奮鬥史》 01

段伏櫪,乙個瘦小,矮小,根本和 帥 這個字粘不上任何關係的普通人。名字的 在於其多讀了幾年書的老爹,總抱著有一天要出書出名乃至於名流千古的美好理想,但可惜現實總是給予他無情的而又現實的打擊,於是就將理想寄望於自己的兒子,起了個 伏櫪 的名,寓意為 老驥伏櫪,志在千里 表達自己不到黃河不死心的良好的願...