编码问题
编码相当于密码本,关系到二进制与看懂的字符之间的对应关系。
密码本的发展史
ascii码:只包含英文字母、数字、特殊字符
0000 0100:(起初是7位,美国设计的,这128种可能足够满足他们的使用需求,之后改为8位,而最左边的位是预留位永远是0)
对于ascii码,表示一个字符需要用8位代表的一个字节
unicode(万国码):就是将是加上所有的文字都汇总在一起,unicode都能够将其表示出来,并与之对应。(编码的根本)
起初unicode:一个字符用16位表示 Z:0000 0000 0101 1010 (不满足对应需求)
最终unicode:一个字符用32位表示 Z:0000 0000 0000 0000 0000 0000 0101 1010 (32位占用资源,浪费,引出utf-8)
utf-8:最少用8位去表示一个字符,是对unicode的升级版(广泛使用)
Z:0101 1010
欧洲文字:0000 0000 0101 1010
亚洲文字:0000 0000 0000 0000 0101 1010
gbk:国标,就是适合自己国家的编码
英文字母:用一个字节表示
中文:用两个字节表示
#字符:组成你看到的内容的最小单位就是字符
#位:二进制中占有的位置,就是位
#字节:8位代表一个字节
编码之间的转换(encode()与decode())
str:在内存中存储是使用的unicode的编码格式,而在传输数据的时候是不允许使用unicode的格式的
bytes:就在传输的时候用到,除了存储的格式为utf-8和表现形式,其余的与str类型几乎是一样的
s = 'shuaiqi' #str的表现形式 b1 = b'shuaiqi' #bytes的表现形式 s1 = '帅气' #str的表现形式 b2 = s1.encode('utf-8') #bytes的表现形式会变为b'\xe4\xb8\xad\xe5\x9b\xbd'
s2=b2.decode('utf-8') #s2输出为 帅气
gbk转换成utf-8
之间可以直接转换(仅限于最初的ascii码所代表的字符)
要通过unicode间接转换
#英文的直接转换 s1 = 'shuaiqi' b1 = s1.encode('gbk') b2 = b1.decode('utf-8') print(b2) #中文的间接转换 s1 = '帅气' b1 = s1.encode('gbk') print(b1) b2 = b1.decode('gbk').encode('utf-8') print(b2)
递归函数
递归函数:就是在函数内调用自身函数
在递归函数执行的过程中,每调用自身函数时会在内存开辟一块临时的名称空间(注意内存的限制,这与死循环不一样);递归到一定的次数就会主动终止,默认的次数一般是998(可以设置默认的次数);一般递归的次数在100次以内,如果超过就要想一下换一种算法来解决问题。
# import sys # sys.setrecursionlimit(100000) #设置次数 # 递归到一定次数,就会主动终止. 998 def func(x): x += 1 print(x) func(x) n = 0 func(n)
详解递归函数
''' 阿一 比 阿二 大两岁 n = 4 阿二 比 阿三 大两岁 n = 3 阿三 比 阿四 大两岁 n = 2 阿四 18岁 n = 1 ''' def age(n): if n == 1: return 26 else: return age(n-1) + 2 print(age(4)) # age(3) + 2 ''' def age(4): if n == 1: return 26 else: return age(3) + 2 def age(3): if n == 1: return 26 else: return age(2) + 2 def age(2): if n == 1: return 26 else: return age(1) + 2 def age(1): if n == 1: return 26 else: return age(0) + 2 print(age(4)) age(4) = 26 + 2 + 2 + 2 '''
二分查找
二分查找法算是最经典最简单的算法(前提:有序的不重复的数字序列)
该算法的基本思路是:目标数值aim与序列中间值mid作比较,当aim>mid时,再找到大的那边的中间值mid,在进行比较;当aim<mid时,再找到小的那边的中间值,在进行比较,直到aim==mid或找不到
l1 = [2, 3, 5, 10, 15, 16, 18] def two_find(l,aim,start=0,end=None): #注意start与end的赋值及存在的作用 end = len(l) - 1 if end is None else end #三元运算符 mid_index = (end - start) // 2 + start ''' 第一次: aim:15 start: 0 end: 6 min_index: 3 中间值:10 aim > 10 第二次: aim:15 start: 4 end: 6 min_index: 5 中间值:16 aim < 16 第三次: aim:15 start: 4 end: 5 min_index: 4 中间值:15 aim = 15 ''' if start <= end: if aim > l[mid_index]: return two_find(l, aim, start=mid_index+1, end=end) elif aim < l[mid_index]: return two_find(l, aim, start=start, end=mid_index) elif aim == l[mid_index]: return mid_index else: return None else: return None print(two_find(l1,15))
比较上下来那个快代码,看看有什么不同
l1 = [2, 3, 5, 10, 15, 16, 18] def two_find(l,aim,start=0,end=None): #注意start与end的赋值及存在的作用 end = len(l) - 1 if end is None else end #三元运算符 mid_index = (end - start) // 2 + start ''' 第一次: aim:15 start: 0 end: 6 min_index: 3 中间值:10 aim > 10 第二次: aim:15 start: 4 end: 6 min_index: 5 中间值:16 aim < 16 第三次: aim:15 start: 4 end: 5 min_index: 4 中间值:15 aim = 15 ''' if start < end: if aim > l[mid_index]: return two_find(l, aim, start=mid_index+1, end=end) elif aim < l[mid_index]: return two_find(l, aim, start=start, end=mid_index) elif aim == l[mid_index]: return mid_index else: return None if start==end and aim == l[mid_index]: #注意这一步 start与end比较情况要分开,对应的情况不同 return mid_index else: return None print(two_find(l1,14))
有什么不对的地方,欢迎指正。