編碼回顧補充:python
回顧編碼問題:
編碼至關於密碼本,關係到二進制與看懂的文字的的對應關係.
最先期的密碼本:
ascii碼:只包含英文字母,數字,特殊字符.
0000 0001:
'fjdskal 我發'
字符:組成你看到的內容的最小單位就是字符.
位:二進制中佔有的位置,就是位.
字節:8位表示一個字節.
對於ascii碼,一個字符是用8位一個字節去表示.
A: 01000001
unicode 萬國碼:將全世界全部的文字都給我彙總到一塊兒.
起初:unicode:
一個字符用16位表示.
A: 0000 0000 0000 0010
中:0000 0000 1000 0010
最終unicode:
一個字符用32位表示.
A: 0000 0000 0000 0010 0000 0000 0000 0010
中:0000 0000 1000 0010 0000 0000 1000 0010
浪費,佔用資源.
utf-8: 最少用8位表示一個字符.對unicode升級,
A: 01000001
歐洲文字: 0000 0000 1000 0010
亞洲文字: 0000 0010 0000 0000 1000 0010
gbk: 國標
英文字母:一個字節表示.中文兩個字節表示.
A: 01000001
中:0000 0000 1000 0010算法
前提:
文件的存儲和傳輸 不能用unicode編碼
除了unicode 剩下的編碼方式不能直接識別.
python3x版本.
int
str ----> 在內存中用的unicode
bytes類型
list
bool
dict
set
tuple函數
英文:
str:
表現形式: s = 'oldboy'
內部編碼: unicode
bytes:
表現形式: b1 = b'oldboy'
內部編碼: 非unicode性能
中文:
str:
表現形式: s = '中國'
內部編碼: unicode
bytes:
表現形式: b1 = b'\xe4\xb8\xad\xe5\x9b\xbd'
內部編碼: 非unicode優化
# s1 = '中國'
# b1 = s1.encode('gbk')
# print(b1)
# b2 = b1.decode('gbk').encode('utf-8')
# print(b2)
# s1 = 'zhong'
# b1 = s1.encode('utf-8')
# print(b1)
# print(b1.decode('gbk'))編碼
------------->>>>>>>>>>>>>遞歸函數<<<<<<<<<<<<<<--------------------------spa
遞歸函數:在一個函數裏在調用這個函數自己。code
遞歸的最大深度:998blog
正如大家剛剛看到的,遞歸函數若是不受到外力的阻止會一直執行下去。可是咱們以前已經說過關於函數調用的問題,每一次函數調用都會產生一個屬於它本身的名稱空間,若是一直調用下去,就會形成名稱空間佔用太多內存的問題,因而python爲了杜絕此類現象,強制的將遞歸層數控制在了997(只要997!你買不了吃虧,買不了上當...).排序
拿什麼來證實這個「998理論」呢?這裏咱們能夠作一個實驗:
def foo(n): print(n) n += 1 foo(n) foo(1)
由此咱們能夠看出,未報錯以前能看到的最大數字就是998.固然了,997是python爲了咱們程序的內存優化所設定的一個默認值,咱們固然還能夠經過一些手段去修改它:
import sys print(sys.setrecursionlimit(100000))
咱們能夠經過這種方式來修改遞歸的最大深度,剛剛咱們將python容許的遞歸深度設置爲了10w,至於實際能夠達到的深度就取決於計算機的性能了。不過咱們仍是不推薦修改這個默認的遞歸深度,由於若是用997層遞歸都沒有解決的問題要麼是不適合使用遞歸來解決要麼是你代碼寫的太爛了~~~
示例講解------------->>>>>>>>>>>
例一:
如今大家問我,alex老師多大了?我說我不告訴你,但alex比 egon 大兩歲。
你想知道alex多大,你是否是還得去問egon?egon說,我也不告訴你,但我比武sir大兩歲。
你又問武sir,武sir也不告訴你,他說他比太白大兩歲。
那你問太白,太白告訴你,他18了。
這個時候你是否是就知道了?alex多大?
遞歸實例:
def age(n): if n == 1: return 40 else: return age(n-1)+2 print(age(4))
----------------------->>>>>>>>>>>>>>>>>>二分數查找<<<<<<<<<<<<<<<<<-----------------------------
若是有這樣一個列表,讓你從這個列表中找到66的位置,你要怎麼作?
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
你說,so easy!
l.index(66)...
咱們之因此用index方法能夠找到,是由於python幫咱們實現了查找方法。若是,index方法不給你用了。。。你還能找到這個66麼?
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] i = 0 for num in l: if num == 66: print(i) i+=1
上面這個方法就實現了從一個列表中找到66所在的位置了。
但咱們如今是怎麼找到這個數的呀?是否是循環這個列表,一個一個的找的呀?假如咱們這個列表特別長,裏面好好幾十萬個數,那咱們找一個數若是運氣很差的話是否是要對比十幾萬次?這樣效率過低了,咱們得想一個新辦法。
二分查找算法
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
你觀察這個列表,這是否是一個從小到大排序的有序列表呀?
若是這樣,假如我要找的數比列表中間的數還大,是否是我直接在列表的後半邊找就好了?
注意:列表必須是有序的,
咱們知道2**16等於65536,也就是說,若是一個列表裏有六萬個數字,咱們用二分數查找,最多16次就可 以找到目標值.
這就是二分查找算法!
那麼落實到代碼上咱們應該怎麼實現呢?
簡單版二分法
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] def func(l,aim): mid = (len(l)-1)//2 if l: if aim > l[mid]: func(l[mid+1:],aim) elif aim < l[mid]: func(l[:mid],aim) elif aim == l[mid]: print("bingo",mid) else: print('找不到') func(l,66) func(l,6)
升級版二分法
l1 = [1, 2, 4, 5, 7, 9] def two_search(l,aim,start=0,end=None): end = len(l)-1 if end is None else end mid_index = (end - start) // 2 + start if end >= start: if aim > l[mid_index]: return two_search(l,aim,start=mid_index+1,end=end) elif aim < l[mid_index]: return two_search(l,aim,start=start,end=mid_index-1) elif aim == l[mid_index]: return mid_index else: return '沒有此值' else: return '沒有此值' print(two_search(l1,9))
人理解函數,神理解遞歸!能夠用下邊的方法多跑幾回程序,慢慢理解!!!