python 高階 chapter3 時間複雜度

2021-09-19 06:06:47 字數 2654 閱讀 2723

關於**的時間複雜度,我們可能在 大學裡 的計算機基礎、 資料結構、 演算法導論 等一系列的課程中,學習或接觸過。幾乎所有計算機系 或 數學計算機系的 都對它們很熟悉,沒一門語言都不會逃過時間複雜度,這個說起來算是非常基礎的知識點了,那我為什麼還要拿到高階裡面來說呢,因為日常中的 剛剛入門的 pythoner或者非科班出身的程式設計師 很少注意他們編寫的程式時間複雜度,掌握好時間複雜度是掌握演算法的很重要的因素,因為演算法初衷就在於降低時間複雜度。

本篇使用 大o計數法來描述時間複雜度,引用維基百科的描述:

下面我會通過一些例子來舉證它的時間複雜度:

def linear_search(l, x):  # 線性搜尋 列表的長度是決定性因素 o(len(l))

for e in l:

if e == x:

return true

return false

線性搜尋的時間複雜度o(n),取決於列表的長度,在時間複雜度上來說它是一種優秀複雜度,因為隨著列表的增長,時間複雜度不會出現**性的增長。

def fact(n):

answer = 1 # 1

while n > 1: # 5 *n

answer *= n

n -= 1

return answer # 1 所有 5n + 2

看到上面的**, answer賦值的時候進行了一步操作, 隨後的while迴圈裡,進行了5步操作,迴圈的時間複雜度取決於 n的大小,所以是5n, 最後return 又是一步操作,所以總的步數為5n+2,仔細算的是這樣,但在大o表示法裡,是忽略常數的(大o表示法通常會忽略常數,因為它關注的是演算法的消耗時間隨著n的變化而怎麼變化,這樣算有沒有弊端呢,有的,就是某些情況下使用大o表示法的時間複雜度是一致的,但實際上是有差異的),所以如果用大o來表示的話,為o(n)。

def factor(n):  # 階乘 o(n)  遞迴

if n == 1:

return 1

else:

return n * factor(n-1)

這段階乘的**,時間複雜度為o(n)

def sqrt_bi(x, eps):  # 2分查詢 30次

low = 0.0

high = max(1, x)

ans = (high + low) / 2.0

while abs(ans**2 - x) == eps:

if ans**2 == x:

low = ans

else:

high = ans

ans = (high + low) / 2.0

return ans

上面這段**,是用python實現的二分查詢,它的的時間複雜度用大o表示法表述為為o(log(n))

def sqrt_exhaust(x, eps):

step = eps ** 2 # 2

ans = 0.0 # 1

while abs(ans**2 - x) >= eps and ans <= max(x, 1): # 8 * 迴圈執行的次數

ans += step

return ans # 1 所有 3 + 8 * 迴圈執行次數

這兩段**的作用是相同的,但兩種方法 輸入100到最後求得結果0.0001 乙個迴圈要花費 8000000 次 (第二種)乙個只需要迴圈30次(第一種),當然這是演算法的問題,只不過體現的是時間複雜度,當你掌握了時間複雜度後,你才會去考慮演算法的優劣性。

def is_subset(l1, l2):   # 多項式 o(len(l1) * len(l2))

for e1 in l1:

matched = false

for e2 in l2:

if e1 == e2:

matched = true

break

if not matched:

return false

return true

上面這段**,演算法執行時間會成二次方的增長,理論上來說,這是相當糟糕的時間複雜度了,但這樣**在新手裡,是非常常見的,我本人初期就寫過很多這樣的**。

def get_subsets(l):    # 指數演算法  漢諾塔 o(2^n)

if len(l) == 0:

return

smaller = get_subsets(l[:-1])

extra = l[-1:]

new =

for small in smaller:

return smaller + new

在這段漢諾塔**裡,並不是平常見到的漢諾塔的寫法,演算法的執行時間會成2的n次方增長,實際上是糟糕的時間複雜度了。

在日常的生產活動中,我們應該竭力尋找時間複雜度小的演算法,如 線性時間,掌握了時間複雜度有助於你寫出或找到更好的演算法,選擇好的演算法也是效能優化的一部分。

python高階學習chapter03(迭代相關)

重要概念!迭代器,可迭代物件,生成器,很容易繞暈了。凡是可以使用for進行迴圈的就是可迭代物件,其中可以通過next方法逐步輸出的就是迭代器,生成器的形成有兩種 一種是把列表生成式改成 一種是帶有yield語句的。具體的可以看 接下來進入主題 如何實現乙個迭代器?實現乙個迭代器 from colle...

C 高階程式設計 Chapter2

預定義資料型別 值型別 和 引用型別 引用型別 指向包含物件的記憶體位置 decimal 128 位精度 十進位制數表示法 不是基本資料型別,會有效能損失,專用於財務計算 byte 8 short 16 int 32 long 64 float 32位精度 double 64位精度 char 16位...

UNIX 環境高階程式設計Chapter 1 2

第一條規則是 如果沒有出錯,則其值不會被乙個例程清除。因此,僅當函式的返回值指明出錯時,才檢驗其值。第二條是 任一函式都不會將 e r r n o值設定為0,在 e r r n o h 中定義的所有常數都不為 0。c標準定義了兩個函式,它們幫助列印出錯資訊。include c h a r s t r...