2、算法分析

1、什麼是算法分析

程序和算法的區別:程序員

  • 算法是對問題解決的分步描述
  • 程序是採用某種編程語言實現的算法,同一個算法經過不一樣的程序員採用不一樣的編程語言,能產生不少程序

算法分析的概念:算法

  • 算法分析主要就是從計算資源消耗的角度來評判和比較算法
  • 更高效利用計算資源,或者更少佔用計算資源的算法,就是好算法

計算資源指標:編程

  • 一種是算法解決問題過程當中須要的存儲空間或內存
  • 另外一種是算法的執行時間

運行時間檢測:app

 1 # 累計求和程序的運行時間檢測
 2 #迭代法
 3 import time
 4 
 5 def sum1(n):
 6     start = time.time()
 7     theSum = 0
 8     for i in range(1,n+1):
 9         theSum += i
10     end = time.time()
11     return theSum, end - start
12     
13 for i in range(5):
14     print('Sum is %d required %10.7f seconds'%sum1(10000))

n = 10000 時,執行5次的結果爲dom

Sum is 50005000 required  0.0000000 seconds
Sum is 50005000 required  0.0009980 seconds
Sum is 50005000 required  0.0000000 seconds
Sum is 50005000 required  0.0000000 seconds
Sum is 50005000 required  0.0009968 seconds

n = 100000 時, 執行5次的結果爲編程語言

Sum is 5000050000 required  0.0049877 seconds
Sum is 5000050000 required  0.0049853 seconds
Sum is 5000050000 required  0.0049860 seconds
Sum is 5000050000 required  0.0049872 seconds
Sum is 5000050000 required  0.0049863 seconds

n = 1000000時,執行5次的結果爲函數

Sum is 500000500000 required  0.0528579 seconds
Sum is 500000500000 required  0.0518231 seconds
Sum is 500000500000 required  0.0528951 seconds
Sum is 500000500000 required  0.0519009 seconds
Sum is 500000500000 required  0.0527823 seconds

 

 1 # 累計求和程序的運行時間檢測
 2 # 利用高斯求和公式的無迭代算法
 3 import time
 4 
 5 def sum2(n):
 6     start = time.time()
 7     theSum = (n * (n+1)) / 2
 8     end = time.time()
 9     return theSum, end - start
10     
11 for i in range(5):
12     print('Sum is %d required %10.7f seconds'%sum2(10000))

n = 10000,100000,1000000時,執行5次的結果時間均相同,爲0.0000000 seconds性能

比較:ui

  • 第一種迭代算法包含一個循環,這個循環運行次數跟累加值n有關,n增長,循環次數也會增長
  • 第二種無迭代算法運行時間比第一種短不少,運行時間與累計對象n的大小無關

2、大O表示法

算法時間度量指標:spa

  • 一個算法所實施的操做數量或步驟數可做爲獨立於具體程序/機器的度量指標
  • 賦值語句是度量指標的一個合適選擇,一條賦值語句同時包含了(表達式)計算和(變量)存儲兩個基本資源

數量級函數(Order of Magnitude)

  • 基本操做數量函數T(n)的精確值不是特別重要,重要的是T(n)中起決定性因素的主導部分
  • 數量級函數描述了T(n)中隨着n增長而增長速度最快的主導部分

常見的大O數量級函數:

 

 

 

 

 3、"變位詞"判斷問題

 1 #解法1:逐字檢查
 2 
 3 def anagramSolution1(s1, s2):
 4     alist = list(s2)
 5     pos1 = 0
 6     stillOK = True
 7     while pos1 < len(s1) and stillOK:
 8         pos2 = 0
 9         found = False
10         while pos2 < len(alist) and not found:
11             if s1[pos1] == s2[pos2]:
12                 found = True
13             else:
14                 pos2 = pos2 + 1
15         if found:
16             alist[pos2] = None
17         else:
18             stillOK = False
19         pos1 = pos1 + 1
20     return stillOK
21     
22 print(anagramSolution1('abcd','cabd'))

 1 #解法2:排序比較
 2 
 3 def anagramSolution2(s1, s2):
 4     alist1 = list(s1)
 5     alist2 = list(s2)
 6     
 7     alist1.sort()
 8     alist2.sort()
 9     pos = 0
10     matches = True
11     while pos < len(s1) and matches:
12         if alist1[pos] == alist2[pos]:
13             pos = pos + 1
14         else:
15             matches = False
16     return matches
17     
18 print(anagramSolution2('abcde','edcba'))

 1 #解法4:計數比較
 2 
 3 def anagramSolution4(s1, s2):
 4     c1 = [0] * 26
 5     c2 = [0] * 26
 6     for i in s1:
 7         pos = ord(i) - ord('a')
 8         c1[pos] = c1[pos] + 1
 9     for j in s2:
10         pos = ord(j) - ord('a')
11         c2[pos] = c2[pos] + 1
12     k = 0
13     stillOK = True
14     while k < 26 and stillOK:
15         if c1[k] == c2[k]:
16             k = k + 1
17         else:
18             stillOK = False
19     return stillOK
20     
21 print(anagramSolution4('abcde','edcba'))

4、Python數據類型的性能

一、列表list和字典dict的對比:

 

 

二、4種生成前n個整數列表的方法性能比較

 

 1 #4種生成前n個整數列表的方法性能比較
 2 from timeit import Timer
 3 
 4 def test1():
 5     l = []
 6     for i in range(1000):
 7         l = l + [i]
 8         
 9 def test2():
10     l = []
11     for i in range(1000):
12         l.append(i)
13         
14 def test3():
15     l = [i for i in range(1000)]
16     
17 def test4():
18     l = list(range(1000))
19     
20 t1 = Timer('test1()','from __main__ import test1') #建立一個Timer對象,指定須要反覆運行的語句和只須要運行一次的「安裝語句」
21 print('concat %f seconds\n' % t1.timeit(number=10000)) #調用Timer對象的timeit方法,其中能夠指定反覆運行多少次
22 
23 t2 = Timer('test2()','from __main__ import test2')
24 print('append %f seconds\n' % t2.timeit(number=10000))
25 t3 = Timer('test3()','from __main__ import test3')
26 print('comprehension %f seconds\n' % t3.timeit(number=10000))
27 t4 = Timer('test4()','from __main__ import test4')
28 print('list range %f seconds\n' % t4.timeit(number=10000))
concat 14.517047 seconds

append 0.859504 seconds

comprehension 0.517713 seconds

list range 0.127913 seconds

 

三、list.pop的計時試驗

# -*- coding: utf-8 -*-
"""
Created on Thu Oct 17 20:30:27 2019

@author: wu
"""

#list.pop的計時試驗,比較pop()和pop(0)兩種方法
from timeit import Timer
import timeit
import numpy as np
import matplotlib.pyplot as plt

pop0 = timeit.Timer('x.pop(0)','from __main__ import x')
popend = timeit.Timer('x.pop()','from __main__ import x')
print('pop(0)        pop()')
l1 = []
l2 = []
for i in range(1000000,10000001,100000):
    x = list(range(i))
    pt = popend.timeit(number=100)
    l1.append(pt)
    x = list(range(i))
    pz = pop0.timeit(number=100)
    l2.append(pz)
    print('%15.5f,%15.5f' % (pz,pt))
    
j = np.arange(1000000,10000001,100000)
plt.plot(j,l1,label='pop')
plt.plot(j,l2,label='pop0')
plt.xlabel('n')
plt.ylabel('time(s)')
plt.legend()
plt.show()

 

 

 四、list和dict的in操做對比

 1 #驗證list中檢索一個值,以及dict中檢索一個值的對比
 2 import timeit
 3 import random
 4 import numpy as np
 5 import matplotlib.pyplot as plt
 6 
 7 l1,l2 = [],[]
 8 n = []
 9 for i in range(10000,1000001,20000):
10     t = timeit.Timer('random.randrange(%d) in x'%i,'from __main__ import random,x')
11     x = list(range(i))
12     lst_time = t.timeit(number=100)
13     l1.append(lst_time)
14     x = {j:None for j in range(i)}
15     d_time = t.timeit(number=100)
16     l2.append(d_time)
17     print('{},{:10.3f},{:10.3f}'.format(i,lst_time,d_time))
18     
19 for i in range(10000,1000001,20000):
20     n.append(i)
21 
22 plt.plot(n,l1,'go-',label='list')
23 plt.plot(n,l2,'r*-',label='dict')
24 plt.xlabel('n')
25 plt.ylabel('time')
26 plt.legend()
27 plt.show()
28     

 

 

相關文章
相關標籤/搜索