《程式設計珠璣》讀書報告

2021-06-01 08:17:57 字數 3558 閱讀 6479

最後幾章還沒怎麼看,先寫這麼多吧。

本章概括的講述了如何用程式解決問題,包括:準確的問題描述、程式設計以及實現。

本章首先提出了乙個問題「如何給磁碟檔案排序?」,並說明應該先對問題進行準確的描述,將已知條件組織成一種更客觀、更易用的形式:輸入、輸出以及約束。在程式設計階段,應該充分理解問題的特點,選擇合適的解決方法。

本章主要講述了如何根據問題的特點,靈機一動,思考出合適的演算法來解決特殊問題。

本章提出了乙個問題:

給定乙個最多包含40億個隨機排序的32位整數的順序檔案,找出乙個不在檔案中的32位整數。

本章在此處提到了二分搜尋,在程式設計中二分搜尋是最常見的用於有序資料的搜尋演算法。對於上面的問題,可以找出其特殊性:2的32

次方為4 294 967 296

,也就是說,無論如何,都至少有乙個整數不在順序檔案中。利用這一點,我們利用二分搜尋的演算法,不同之處在於,每次取中間數字,然後統計中間數字之上和之下的元素個數,若之上的元素個數大於之下的元素個數,則說明之下必然有乙個缺失整數。

上題的解決方法利用了題目的特殊性:題目僅僅要求找出乙個不在檔案中的整數,且整數範圍大於整數個數,同時,結點二分搜尋的原理(原理,必須於演算法充分理解,理解其思路,活用演算法)。

本章提出的第二個問題:

將乙個n元一維向量向左旋轉i個位置。例如,當n=8且i=3時,abcdefgh旋轉為defghabc。

該功能是微量的乙個基本操作。旋轉操作對應於交換相鄰的不同大小的記憶體塊:每當拖動檔案中的一塊文字到其它地方時,就要求程式交換兩塊記憶體中的內容,在許多場合下,運動時間和儲存空間的約束會很嚴格。

最基本的解決方法是:移動x[0]

到臨時變數

t,然後移動

x[i]

到x[0]

,x[2i]

到x[i]

,依次類推,直到返回到取

x[0]

中的元素,改為從

t中取值,然後終止過程。從另一方面,旋轉向量

x其實就是交換

ab得到

ba,假定有乙個函式

reverse

,從ab

開始,首先對

a翻轉,然後對

b翻轉,最後再整體翻轉,此時得到的恰好就是ba。

本章的中心思想是:使用基本操作來使得問題得到簡化。

恰當的資料檢視決定了程式的結構。

本章提到了一種解決格式信函的方法:報表模板。方法比較簡單巧妙,報告中略去。

本章提到了一種早期的資料結構:平行陣列,即通過元素數相同且下標對應的一組陣列表示緊密相關的資訊,該資料結構已由struct

取代。

本章提出了乙個解決問題的思路:「更一般性的問題也許更容易解決」,這意味著,直接編寫解決23

種情況的問題很困難,而編寫乙個處理

n種情況的通用程式,再令

n=23

來得到最終結果,卻相對要容易一些。

本章提出了思考時的幾條原則:

l 使用陣列重新編寫重複**。冗長的相似**常常可以使用最簡單的資料結構——資料來更好的表述。

l 封裝複雜結構。當需要非常複雜的資料結構時,使用抽象術語進行定義,並將操作表示為類。

l 盡可能使用高階工具。

l 從資料得出程式的結構。

本章的主題就是:通過使用恰當的資料結構來替代複雜的**,從資料可以得出程式的結構。萬變不離其宗:在動手編寫**之前,徹底理解輸入、輸出和中間資料結構,並圍繞這些結構建立程式。

本章對前面三章進行了乙個簡單的總結:問題定義、演算法設計、資料結構的選擇。

本章同時提出了程式驗證對於編寫程式的重要性。程式驗證的乙個主要好處就是,為程式設計師提供一種語言,用來表達他們對程式的理解。

程式文字中重要的解析以斷言的形式結束。輸入、程式變數和輸出之間的關係描述了程式的「狀態」,斷言使得程式設計師可以準確闡述這些關係。

測試過程中,違反斷言語句的那些情況指明了程式的錯誤所在,而對相應情況形式的分析則指出了在不引入新錯誤的情況下如何修正程式中的錯誤。除錯過程中,需要同時修正錯誤**和錯誤的斷言:總是保持對**的正確理解。斷言在程式維護過程中至關重要:當你拿到一段你從未見過而且多年來也沒有其他人見過的**時,有關該程式狀態的斷言對於理解程式是很有幫助的。

本章提出了一些程式設計方面的小技巧以及細節。

斷言的藝術:斷言既可以用來指導程式**的開發,也可以用來判斷程式的正確性。

編碼:對於比較難寫的函式,最容易的訪求是使用方便的高階偽**來構建程式框架,然後將偽**翻譯成要實現的語言。

本章概述了幾種提高程式效能的方法:優化演算法以及資料結構、在每個時間步對資料結構進行重新配置、**調優以及改善硬體。

本章引入了估算的概念與重要性。

快速檢驗:第乙個法則是和式中各項的量綱必須相同,第二個法則是乘積的量綱是各乘數量綱的乘積。

「72法則」:假設以年利率r%投資一筆錢y年,金融版本的「72法則」指出,如果r*y=72,那麼你的投資差不多會翻倍。

72法則用於估算指數過程的增長非常便利。

π秒就是乙個納世紀。

效能估計:可以通過一些小實驗來獲得關鍵引數,進而對程式效能進行估計。

通過使用很大的安全係數來補償自己的知識侷限,保證正確性。

little定律:

考慮乙個帶有輸入和輸出的任意系統,little定律指出「系統中物體的平均數量等於物理離開系統的平均速率和每個物體在系統中停留的平均時間的乘積。」

在進行粗略估算時,切記:任何事都應盡量簡單,但不宜過於簡單。簡單計算並不是特別簡單,其中包含了安全係數,以補償估算引數時的錯誤和對問題的了解不足。

複雜深奧的演算法有時可以極大提高程式效能。

本章提出了乙個小問題,並針對這一問題研究了4

種不同的演算法。

問題的輸入是具有n

個浮點數的微量

x,輸出是輸入向量的任何連續子向量中的最大和。

針對這一問題,本章首先研究了普通的遍歷演算法,數量級為o(n3),進行研究了兩個平方演算法。最終,利用分治演算法的思想,提出了乙個

o(n*logn)

的演算法:使用類似於分治演算法的原理,前

i個元素中,最大總和子陣列要麼在前

i-1個元素中,要麼其結束位置為i。

maxsofar = 0

maxendinghere = 0

for i = [0, n)

maxendinghere = max(maxendinghere + x[i], 0)

maxsofar = max(maxsofar, maxendinghere)

本章給出了幾個重要的演算法設計技術:

儲存狀態,避免重複計算;

將資訊預處理至資料結構中;

分治演算法;

掃瞄演算法;

累積;下界,估算演算法的效能下界;

「**調優」首先確定程式中開銷較大的部分,然後進行少量修改,以提高其執行速度。

快取記憶體原理:最經常訪問的資料,其訪問開銷應該是最小的,可以將最覺型別的空閒記錄快取。

c語言的模運算子

%開銷較大。

在現代的體系結構中,如果對記憶體的訪問戰勝了大量的執行時間,那麼減少計算時間是毫無意義的。

**調優的最重要原理就是盡量少用它。

高效處理常見情況。

使用巨集替代函式來打破函式層次。

修改資料結構。

展開迴圈,消除迴圈開銷。

numpy的讀書報告

numpy numpy是python中科學計算的基礎包。它是乙個python庫,提供多維陣列物件,各種派生物件 如掩碼陣列和矩陣 以及用於陣列快速操作的各種api,有包括數學 邏輯 形狀操作 排序 選擇 輸入輸出 離散傅利葉變換 基本線性代數,基本統計運算和隨機模擬等等。numpy包的核心是 nda...

matplotlib的讀書報告

matplotlib是python的乙個2d圖形庫,能夠生成各種格式的圖形 諸如折線圖,散點圖,直方圖等等 介面可互動 可以利用滑鼠對生成圖形進行點選操作 同時該2d圖形庫跨平台,即既可以在python指令碼中編碼操作,也可以在jupyter notebook中使用,以及其他平台都可以很方便的使用m...

scipy的讀書報告

scipy 提供了複製的演算法及其在 numpy 中作為函式的用法。這將分配高階命令和多種多樣的類來操作和視覺化資料。scipy 將多個小型包整合在一起,每個包都針對單獨的科學計算領域。其中的幾個子包是linalg 線性代數 constants 物理和數學常數 和sparse 稀疏矩陣和相關例程 值...