Ⅰ 編程之美和編程匠藝哪本書比較好
在編程領域,有許多備受推崇的書籍,它們各自有著獨特的魅力和價值。《編程珠璣(第二版)》深入淺出地探討了程序設計中的精髓,不僅涵蓋了演算法與數據結構的基礎知識,還通過具體的例子展示了如何優化代碼和提高程序性能。這本書適合有一定編程基礎的讀者,能夠幫助他們提升編程技巧,更好地應對實際工作中的挑戰。
另一本同樣值得推薦的是《高效程序的奧秘》。這本書從不同角度分析了程序設計中的高效性問題,不僅講解了如何編寫高效的代碼,還涉及到了系統層面的優化策略。書中通過大量的實例和實際案例,讓讀者能夠直觀地理解高效程序設計的重要性,並學會如何在開發過程中實現高效性。
《編程之美:微軟技術面試心得》這本書則側重於技術面試的技巧與經驗分享。它詳細記錄了微軟公司面試過程中的經典問題和解決方案,同時提供了許多實用的建議和策略,幫助讀者在技術面試中脫穎而出。這本書不僅適合即將參加技術面試的程序員,也適合那些希望提升自己技術能力的專業人士。
《代碼優化:有效使用內存》一書專注於內存管理方面的知識和技巧。通過深入剖析內存分配機制、垃圾回收原理等內容,書中提供了多種優化內存使用的方法和策略。對於那些需要處理大量數據或資源受限環境下的程序設計人員來說,這本書提供了寶貴的指導。
《代碼之美》這本書則更多地關注於代碼的美學與風格。它探討了如何編寫優雅、可讀性強且易於維護的代碼,強調了良好的編程習慣和規范的重要性。這本書不僅適合初學者學習,也適合有一定經驗的開發者作為提高代碼質量的參考。
《編程匠藝(中文版)》則是一本強調實踐與經驗積累的書籍。它通過大量實例和實戰經驗,展現了如何在實際項目中運用各種編程技巧和最佳實踐。這本書特別適合那些希望在實際工作中提升自己編程能力的專業人士。
Ⅱ 學的c++能看《編程之美》嗎
可以的。
《編程之美——微軟技術面試心得》收集了約60道演算法和程序設計題目,這些題目大部分在近年的筆試,面試中出現過,或者是被微軟員工熱烈討論過。作者試圖從書中各種有趣的問題出發,引導讀者發現問題,分析問題,解決問題,尋找更優的解法。
這本書裡面主要涉及到的是各種演算法的討論,以及對程序設計思路的引導。對於任何語言的學習者都是有幫助的。其中大部分演算法描述更是採用了C語言作為例子,所以,學習C++看編程之美是沒有障礙的。
但是,由於這本書裡面涉及到的一些演算法比較困難,對於初學者來說會有些偏難,所以最好在C++有一定功底後再去閱讀。
Ⅲ 搞編程的我是個演算法渣,怎麼樣能很快的提升演算法水平有什麼必要的或者非常基礎的演算法需要掌握
演算法的實現需要你對數據結構有充分的理解,我個人覺得數據結構是演算法的基礎,至少我是先熟悉數據結構再弄演算法的,這樣接受起來比較快。所以建議你
1:先花些時間掌握數據結構知識,比如數據結構基本類型;線性表、樹、圖、集合的存儲表示以及他們的應用,而要想熟練運用這些線性表、樹、圖、集合,那麼又必須要非常熟練棧和隊列,因為棧和隊列是必不可少的,如果你非常熟練運用棧和隊列,那麼你肯定能輕松搞定牽涉到線性表、樹等這些應用的。
2:掌握基本的查找演算法和排序演算法;因為有了上述數據結構的鋪墊,也較容易接受查找和排序演算法在計算機內部的組織形式,對於運用計算機思想思考問題有很大的幫助。
3:學習常用的演算法思想,如分治、貪心、動態規劃、回溯等等。學習之後自己動手找一些題目敲敲代碼,剛開始可以按照答案敲,慢慢要丟開答案自己來組織思路了。
4:要熟悉分析演算法的復雜度,因為接著要開始思考代價問題了,包括時間和空間的開銷。
其實用誰的書都無所謂,只要內容齊全了,而你自己閱讀起來接受得更好就用誰的。如果還有時間,推薦你看看朱東生趙建利等的《新編數據結構演算法 考研指導》(當時我考研用來輔助看的,裡面講解的遞歸與非遞歸之間的轉換非常好)。
5:如果有興趣可以看看《編程珠璣》和《編程之美》,有些企業招聘時會從中挑個別題目出題。
總之,我覺得數據結構是基礎,演算法是靈魂。多思考,多運用就能熟能生巧了。工科類的不多動動手那些知識是很容易生疏的。
以上觀點僅供參考,純屬個人觀點。
Ⅳ 求高手用c++解決二十四點的問題,具體如下
24點演算法分析
很久沒有研究程序了,慚愧中。。。這個夏天大致地翻了一下微軟亞洲研究院出的《編程之美》,很喜歡這本書的風格,裡面很多題目都很有意思。書中主要突出的是一個「巧」字,最關鍵的,就是從變化中尋找不變的規律。 這次說的問題其實也很簡單,給四個數,寫一個程序輸出算24點的結果,如果沒有就輸出「No Answer」。但是如果用我們自己算24點的思維來寫程序是不行的,因為那屬於一種「湊」的方法,有碰巧和經驗的成分。計算機能做的,就是通過一種固定的方式來找尋結果。如果沒有一般性的所謂「固定」方式,那麼只有通過遍歷和窮舉來解決問題。這樣的方法下誕生了很多所謂的NP難問題,如果原始數據規模比較大就要花很長的時間來得到結果。
24點這個問題最直接的方法就是,列舉四個數所有的排列組合,加上各種運算符以及括弧,所有的情況經過處理之後可以得到一個包含所有計算結果和計算式的列表,從其中尋找24的影蹤就可以了。如果不計計算結果重復的情況,最終的結果有7680種,數據量還是有點大,因此這個演算法需要進一步的優化。例如,考慮到加法和乘法的交換律,如果遇到相應的情況只計算一種,對於另一種直接返回。這樣的剪枝處理可以減少不少的運算。
不過我用的是書中的另一種思路,採用了劃分的思想。具體的演算法是:
如果A是一個數組,定義f(A)為數組中的所有數經過四則運算所能得到的結果的集合。對於A中元素個數大於1的情況,可以將A分拆成兩個集合,定義運算 Fork(A,B)為f(A)和f(B)中各取一個元素的四則運算得到的所有的結果的集合。這樣,如果列舉出集合A所有的拆分情況,那麼所有Fork結果的並集就是f(A)的結果。
對於24點的情況,因為數組A有4個數,因此將其用各種方法拆分即可得到最終的f(A),然後查詢其中是否存在元素24即可得到有解或者無解的判斷。
需要說明的有幾點:
1.這個問題表面上需要採用遞歸的演算法,即如果只有一個元素那麼直接返回,否則將問題轉化為多個f的計算,而每個f的計算又要經過轉化,層層遞歸,直至只有一個元素的情況。但是,不要忘了遞歸的方法一般都是針對回溯次數不確定的問題。例如漢諾塔問題,只有一個盤子的情況和64個盤子的情況,回溯次數截然不同,千差萬別;但是對於24點,因為只有4個數,實際上分拆的可能性是固定的,就那麼有限種情況。遞歸演算法的思路是從樹的根部往下遍歷,而且一般不知道樹的大小和規模。而對於24點問題,這棵樹的大小固定,完全可以從樹的葉子著手,從葉子向根步進,從而得到最終的結果。
2.分拆有一定的技巧,最合適的方法是通過位運算。比如一種分拆方法是{a1,a2},{a3,a4},那麼寫做1100和0011。這種方法的好處在於,比如要判斷1000是不是1100的一個子集,只需要將兩者做與運算,最後的結果如果還等於1100則表明確實是子集,同時分拆的另一個結果便是兩者的差。這樣至多隻需要比較 10多次就可以列舉出每個集合所有的分拆情況,比較巧妙的方法。同時,位運算的速度也很快,不會對計算的時間有較大的影響。
3.這個方法的缺點在於,最終得到的只是一個無解或者有解的判斷,並沒有輸出表達式。
所以我對這個演算法進行了一定的改進,使之能輸出表達式。
首先要考慮的,也是最重要的,是這個程序的數據結構。最終的目的自然是為了達到最少的時間復雜度。由於上述方法中f函數返回的是「集合」,因此不存在重復的元素。這樣的情況下,哈希表自然是首選的數據結構。
為了記錄表達式,需要引入另一套數據結構。每一個計算的結果都必須和一個表達式對應。這樣,當最終查詢到一個計算結果為24的時候,只需查找相應的表達式就可以得到結果。
這里就產生了沖突。哈希表的特點是存放是亂序的,也就是說,如果只採用一個哈希表存放計算結果,用一個vector存放表達式,那麼無法產生對應關系。
因此,有兩種方案:
第一種方案比較節省存儲空間,將計算結果和表達式分別存在兩個vector中,由於兩者都是有序的集合類,因此可以在插入數據的時候令各自的下標對應,這樣就可以方便地得到對應關系。但是,這樣做的後果是,在插入新數據的時候需要在vector中查找是否已經存在這個計算結果,如果已有則不必插入。 vector的查找是窮舉式的,效率比較低,尤其是當vector比較大的時候將很大程度上影響計算的效率。但如果不進行查找,勢必會計算很多沒有意義的重復結果,這樣就失去了這個演算法的意義了。
第二種方案在第一種方案的基礎上將計算結果多存一份哈希表數據。這樣做增加了存儲空間,但是在時間上的優勢是顯而易見的。在插入的時候,通過查找哈希表來決定是否已經存在這個結果,由於哈希表的查找效率很高,因此這一步不會對這個程序造成時間上的瓶頸。如果不存在,那麼同時在哈希表和兩個vector中同時插入數據即可。計算結果和表達式的對應關系依然存在,同時查找的效率也大大提高,整個程序的時間復雜度大大降低。這是典型的空間換時間的方法。
寫演算法我首選的語言還是c++,但是很慚愧c++的HashTable我不會用,因此用java寫了一個版本,還算比較成功,能輸出最終的結果。在寫程序前我寫了一個小程序來測試java的HashSet和ArrayList的查找效率,結果很令人驚訝。在10000次查詢中,HashSet所用時間為0ms,而ArrayList則用了1300多ms,看來這個效率完全不是一個數量級上的。因此我採用了上述的第二種方案,最終的效果還不錯。
曾經有人問過我5,5,5,1怎麼算24點,當時想了很久都沒想出來。現在用這個程序可以很輕松地算出5*(5-1/5)=24。看來這個程序可以輸出一些大家想不到的結果,很強大把。類似的例子還有很多,比如3,3,7,7等等。總之呢,優化了的窮舉法(我這個程序實際上還是一種變相的窮舉)是一種很不錯的解決問題的思路,值得採用!
過幾天就開學了。也許每年的開學前才有時間去研究下這種問題,等到開學之後就基本沒什麼時間了。嗯,好好工作把,也願今年能開個好題,明年好好做畢設。Good luck。
PS:昨天經同學提醒才發現有更好的解決方法。主要是因為好久沒用,把java的HashMap給忘了。這個數據結構用在這里正合適,也就是說不用兩個HashSet加兩個ArrayList解決了,直接存在一個HashMap裡面就可以。
具體的做法是:把計算結果存在map的key中,而表達式存在map的value中,問題徹底解決。map中key的查找效率是很高的,同時插入也很快;當找到一個計算結果為24的時候直接根據這個key去尋找相應的value即可得到完美的答案,同時HashMap也保證了每個計算結果只保留一個表達式,避免了重復。
我做了一下性能測試,總的來這個改進後的版本效率比以前的版本略有提高,但是最關鍵的是大大減少了空間的存儲,因此也算是對程序進行的大優化把我想。這兩天看這個帖子似乎看的人比較多哈,也願我的想法能給大家一些啟發。