第一节:概述
1.课程定位:Python语言基础之后的进阶课程,将数据组织起来,有效处理以解决问题
2.计算的概念
2.1基于有穷观点的能行方法:有限数量的明确指令——有限步骤后终止——每次执行都能得到唯一结果且可以被精确执行
2.2二十世纪三十年代:递归函数模型、lambda演算模型、post机模型、图灵机模型
2.3图灵机的规则
<状态1,读取字符,改写字符,状态2,状态的操作>
e.g.<读写头位于第一个字符处,读取第一个字符a,改写第一个字符a为空格,读写头向右移动,右移>
第二节:算法和计算的复杂性
1.问题的分类
what:是什么?面向判断与分类的问题——通过树状判断分支进行解决
why:为什么?面向求因与证明的问题——通过有限的公式序列进行解决
how:怎么做?面向过程与构建的问题——通过算法流程解决
注:解决一类大问题时往往需要将其拆解为上述的单元进行解决。
2.计算复杂性:定义一些衡量指标,对问题的难易程度(所需执行步骤数和存储空间大小)进行分类
3.突破计算极限
3.1超大规模分布式计算
3.2新型计算技术:光子计算,DNA计算,量子计算(不同于传统的电子计算机)
3.3分布式智慧:众包
e.g.Foldit :游戏化众包蛋白质结构分析
第四节:抽象与实现
1.逻辑层次-接口(可以理解为应用层次、功能层次;抽象发生在不同的层次上)
2.物理层次-实现(硬件结构、操作系统原理、网络协议)
3.算法+数据结构=程序
4.程序设计语言实现算法的基本机制
程序设计语言需要为算法的实现提供实现“过程”和“数据”的机制,具体表现为“控制结构”和“数据类型”
4.1程序设计语言均有语句对应控制结构:顺序处理、分支选择、循环迭代
4.2程序设计语言也提供最基本的数据类型来表示数据:整数、字符等
5.ADT抽象数据类型
5.1抽象数据类型可以实现对于数据的封装
5.2对数据实现“逻辑”层次和“物理”层次的分离,可以定义复杂的数据模型来解决问题,而不需要立即考虑此模型如何实现(可以理解为电动汽车和汽油车的接口都是相同的,但是其实现层面是不同的)
第五讲:算法分析
1.算法分析主要就是从计算资源消耗的角度来评判和比较算法:更高效利用计算资源,或者更少占用计算资源的算法,就是好算法
2.计算资源指标
计算资源包括:存储空间或内存(此评价指标随着数据的不同差异较大,无法方便标准地比较);算法的执行时间
3.例子:使用time函数检测算法运行时间
import time
#迭代型算法:时间随数值大小线性增长
def sumOfN2(n):
start =time.time( )
theSum = 0
for i in range(1, n + 1):
theSum = theSum + i
end = time.time()
return theSum, end-start
for i in range(5):
print ( "Sum is %d required %10.7f seconds" %sumOfN2(100000))
#非迭代型算法:时间几乎不增长
def sumOfN3(n ):
start = time.time( )
theSum = (n * (n + 1))/ 2
end = time.time( )
return theSum,end - start
for i in range(5):
print ( "Sum is %d required %10.7f seconds" %sumOfN3(100000))
4.算法运行时间的检测方法
4.1上述的time函数会随着编程语言与计算机类型而改变,并不标准。
4.2目前主要用大O表示法进行估计——一个算法所实施的操作数量或步骤数可作为独立于具体程序/机器的度量指标(实际情况中以赋值语句的数量作为度量指标)
4.3算法分析的目标是要找出问题规模会怎么影响一个算法的执行时间
4.4数量级函数Order of Magnitude
数量级函数描述了T(n)中随着n增加而增加速度最快的主导部分。称作“大O”表示法,记作O(f(n)),其中f(n)表示T(n)中的主导部分(注:T(n)为赋值语句步骤数)
第六讲:变位词的判断问题
解法一:逐字检查
def anagramSolution1(s1,s2):
alist = list(s2) #将字段S2复制到列表中
pos1 = 0 #表示s1中的第n个数
stillOK = True #判断是否为变位词的参数,true表示是变位词
while pos1 < len(s1) and stillOK: #当s1中的数还没有全部取完并且目前没有找到不匹配的字符,就继续循环
pos2 = 0 #表示s2中的第n个数
found = False
while pos2 < len(alist) and not found : #对于s1中挑出来的一个字母,对s2中所有的字母都进行匹配
if s1[pos1] == alist[pos2]:
found = True
else:
pos2 = pos2 + 1
if found: #如果在上一个循环中找到了,则做✔处理,将s2中的元素消除掉,避免重复
alist[pos2] = None
else:
stillOK = False #如果不是则退出循环,结束
pos1 = pos1 + 1
return stillOK
print(anagramSolution1("douhuanqiu","houduanqiu"))
问题规模:词包含的字符个数n
解法二:排序解法
将字符先按照字母顺序排序,然后从开头逐个进行对比
def anagramSolution2(s1,s2):
alist1 = list(s1)
alist2 = list(s2)
alist1.sort()
alist2.sort()
pos = 0
matches = True
while pos < len(s1) and matches:
if alist1[pos] == alist2[pos]:
pos = pos + 1
else:
matches = False
return matches
print (anagramSolution2("douhuanqiu","houduanqiu"))
这一个方法的主导算法实际上是sort的方法,大致为O(n^2)或O(n*logn)的数量级
解法三:暴力法
将s1中的字母进行全排列,穷尽所有排列的可能性,然后看s2是否属于s1全排列中的一个。(n个字符全排列,可能的组合数量为n!)
解法四:计数比较
对比两个词中每个字母出现的次数,如果26个字母出现的次数都相同的话,这两个字符串就一定是变位词
def anagramSolution4(s1,s2):
c1 = [0] *26
c2 = [0] *26
for i in range(len(s1)):
pos = ord(s1[i]) - ord('a')
c1[pos] = c1[pos] + 1
for i in range(len(s2)):
pos = ord(s2[i]) - ord('a')
c2[pos] = c2[pos] + 1
j = 0
stillOK = True
while j < 26 and stillOK: #对两个作为计数器的列表进行比较
if c1[j] == c2[j]:
j = j + 1
else:
stillOK = False
return stillOK
print (anagramSolution4("douhuanqiu","houduanqiu"))
总操作次数T(n)=2n+26,其数量级为O(n),为目前所有方法中最优的解法。(是一个线性复杂度的算法)
第七讲:python数据类型的性能
Python两种内置数据(list,dict)类型上各种操作的大O数量级
5:37