先來看一道題:
如果 a+b+c=1000,且 a^2+b^2=c^2(a,b,c 為自然數),如何求出所有a、b、c可能的組合?
a^2在pyhton裡,使用a**2表示range()函式,預設從0開始「數數」,一直數自然數到「顧頭不顧腚」的左[右)區間,, 是str.format()的佔位符採用窮舉法,即迴圈的3層巢狀
# -*- coding:utf-8 -*-
# author:marlon kang
#如果 a+b+c=1000,且 a^2+b^2=c^2(a,b,c 為自然數),如何求出所有a、b、c可能的組合?
#定義初始變數
a = 0
b = 0
c = 0
#採用窮舉法,即迴圈的3層巢狀
for a in range(1001):
for b in range(1001):
for c in range(1001):
#python的邏輯運算子,使用"and"而不是「&&」
if a**2 + b**2 == c**2 and a+b+c ==1000:
print("a=,b=,c=".format(a,b,c))
上述演算法還有很大的優化空間,由於有等式關係,故可以少迴圈遍歷一次
#採用窮舉法的改進寫法,即迴圈的2層巢狀+等式變換的限定條件
for a in range(1001):
for b in range(1001):
c = 1000-a-b
#python的邏輯運算子,使用"and"而不是「&&」
if a**2 + b**2 == c**2:
print("a=,b=,c=".format(a,b,c))
輸入: 演算法具有0個或多個輸入
輸出: 演算法至少有1個或多個輸出
有窮性: 演算法在有限的步驟之後會自動結束而不會無限迴圈,並且每乙個步驟可以在可接受的時間內完成
確定性:演算法中的每一步都有確定的含義,不會出現二義性
可行性:演算法的每一步都是可行的,也就是說每一步都能夠執行有限的次數完成
對於演算法的時間效率,我們可以用「大o記法」來表示。
時間複雜度:假設存在函式g,使得演算法a處理規模為n的問題示例所用時間為t(n)=o(g(n)),則稱o(g(n))為演算法a的漸近時間複雜度,簡稱時間複雜度,記為t(n)
對於演算法的時間性質和空間性質,最重要的是其數量級和趨勢,這些是分析演算法效率的主要部分。而計量演算法基本運算元量的規模函式中那些常量因子可以忽略不計。例如,可以認為3n2和100n2屬於同乙個量級
對於最壞時間複雜度,提供了一種保證,表明演算法在此種程度的基本操作中一定能完成工作。
我們主要關注演算法的最壞情況,亦即最壞時間複雜度。
基本操作,即只有常數項,認為其時間複雜度為o(1)
順序結構,時間複雜度按加法進行計算
迴圈結構,時間複雜度按乘法進行計算
分支結構,時間複雜度取最大值判斷乙個演算法的效率時,往往只需要關注運算元量的最高次項,其它次要項和常數項可以忽略
在沒有特殊說明時,我們所分析的演算法的時間複雜度都是指最壞時間複雜度
t(n) = o(n*n*n) = o(n3)
t(n) = o(n*n*(1+1)) = o(n*n) = o(n2)
由此可見,我們嘗試的第二種演算法要比第一種演算法的時間複雜度好多的。
執行次數函式舉例
階非正式術語
12o(1)
常數階2n+3
o(n)
線性階3n2+2n+1
o(n2)
平方階5log2n+20
o(logn)
對數階2n+3nlog2n+19
o(nlogn)
nlogn階
6n3+2n2+3n+4
o(n3)
立方階2n
o(2n)
指數階注意,經常將log2n(以2為底的對數)簡寫成logn
所消耗的時間從小到大
o(1) < o(logn) < o(n) < o(nlogn) < o(n2) < o(n3) < o(2n) < o(n!) < o(n^n)
class timeit.timer(stmt='pass', setup='pass', timer=) timer是測量小段**執行速度的類。timer引數是乙個定時器函式,與平台有關。
timeit.timer.timeit(number=1000000) timer類中測試語句執行速度的物件方法。 number引數是測試**時的測試次數,預設為1000000次。方法返回執行**的平均耗時,乙個float型別的秒數。
# coding:utf-8
from timeit import timer
## li = [i for i in range(10000)]
## li = list(range(10000))
def t3():
li = [i for i in range(10000)]
def t4():
li = list(range(10000))
# number引數是測試**時的測試次數,預設為1,000,000次
timer3 = timer("t3()", "from __main__ import t3")
print("[i for i in range]:", timer3.timeit(number=10000))
timer4 = timer("t4()", "from __main__ import t4")
print("list(range()):", timer4.timeit(number=10000))
# def t6():
# li =
# for i in range(10000):
## def t7():
# li =
# for i in range(10000):
# li.insert(0, i)
# timer6 = timer("t6()", "from __main__ import t6")
## timer7 = timer("t7()", "from __main__ import t7")
# print("insert(0)", timer7.timeit(1000))
表1
表2
程式 = 資料結構 + 演算法
總結:演算法是為了解決實際問題而設計的具體思路,資料結構是演算法需要處理的問題載體
最常用的資料運算有五種:
基於python的基本函式
什麼是函式?函式就是將一段 寫在一起,如果需要使用,直接呼叫即可 就是封裝一段功能 的 塊,這段 可以被多次使用 def define 定義 函式名稱命名規範 單詞全部小寫,多個單詞之間用 連線,函式名要和實現 的功能有關係,做到見名知意 def 函式名 引數列表 函式功能 def eat prin...
python資料結構 演算法引入
如果 a b c 1000,且 a 2 b 2 c 2 a,b,c 為自然數 如何求出所有a b c可能的組合?import time start time time.time for a in range 0,1001 for b in range 0,1001 c 1000 a b if a b...
CakePHP引入基於正規表示式的基本使用者檢驗
通過引入基於正規表示式的基本使用者檢驗,您現在應該已經簡要了解了 cakephp 資料檢驗。通過定義自己的正規表示式來執行資料檢驗,可以在 tor 內練習進一步控制各個表單字段的成功 失敗條件。資料庫設計 table create table users create table users id ...