1算法分析——数据结构与算法Python版学习笔记
什么是算法分析?
计算资源指标:一种是算法解决问题过程中需要的储存空间或内存,另一种是算法的执行时间
运行时间检测
time模块,获取计算机系统当前时间
例如:
方法一:累计求和程序的运行时间检测
import timedef sumOfN2(n):start = time.time()theSum = 0for i in range(1, n + 1):theSum = theSum + iend = time.time()return theSum, end - startfor i in range(5):print("Sum is %d required %10.7f seconds"% sumOfN2(10000))
Error:第一次输入没有在def的函数名括号里填n
后来搜索明白,括号里必须有一个占位符,专业的说是在类的函数内引入变量
方法二:无迭代的累计算法(利用求和公式)
#只改def这一段
def sunOfN3(n):start = time.time()theSum = (n*(n+1))/2end = time.time()return theSum, end - start
新算法运行时间几乎与需要累计的数目无关
“大O表示法”
大O表示法:表示了所有上限中最小的那个上限
数量级函数Order of Magnitude f(n)
例如:
代码赋值语句可以分为4个部分
T(n)=3+3n2+2n+1=3n2+2n+4T(n)=3+3 n^{2}+2 n+1=3 n^{2}+2 n+4 T(n)=3+3n2+2n+1=3n2+2n+4
仅保留最高阶项n^2,去掉所有系数,数量级O(n2)O\left(n^{2}\right)O(n2)
a = 5
b = 6
c = 10
for i in range(n):for j in range(n):x = i * iy = j * jz = i * jfor k in range(n):w = a * k + 45v = b * bd = 33
“变位词”判断
"变位词"判断问题
问题描述:所谓"变位词"是指两个词之间存在组成字母的重新排列关系,如:heart和earth
解题目标:写一个bool函数,以两个词作为参数,返回这两个词是否变位词
解法1:逐字检查
将词1中的字符逐个到词2中检查是否存在
存在就“打勾”标记
如果每个字符都能找到,则两个词就是变位词
只要有1个字符找不到,就不是变位词
为了简单,假设参与判断的两个词仅由大小写字母构成,且长度相等
def anagramSolution1(s1,s2):alist = list(s2)#复制s2到列表pos1 = 0stillOK =Truewhile pos1 < len(s1) and stillOK:#循环s1的每个字符pos2 = 0found = Falsewhile pos2 < len(alist) and not found:if s1[pos1] == alist[pos2]:#在s2逐个对比found = Trueelse:pos2 = pos2 + 1if found:alist[pos2] = None#找到,打勾else:stillOK = False#未找到,失败pos1 = pos1 + 1return stillOKprint(anagramSolution1('abcd','dcba'))
这段值得学习的是 stillOK=True 增加了代码的可读性
实现“打勾”标记:将词2对应字符设为None
注意:字符串是不可变类型,需要先复制到列表中,如果没有复制会报错
总执行次数n+n-1+n-2+…+3+2+1
数量级为O(n^2)
解法2:排序比较
将两个字符串都按照字母顺序排好序
再逐个字符对比是否相同,如果相同则是变位词
def anagramSolution2(s1,s2):alist1 = list(s1)alist2 = list(s2)#转为列表alist1.sort()alist2.sort()#分别排序pos = 0matches = Truewhile pos < len(s1) and matches:if alist1[pos] == alist2[pos]:#逐个对比pos = pos + 1else:matches = Falsereturn matchesprint(anagramSolution2('abcde','edcba'))
本算法时间主导的步骤是排序步骤
后面的学习将会知道排序算法的时间数量级差不多是O(n^2)或者O(n log n),大过O(n)
解法3:暴力法
穷尽所有可能的组合n!个
将s1中出现的字符进行全排列,再查看s2是否出现在全排列列表中
解法4:计数比较
对比两个词中每个字母出现的次数,如果26个字母出现的次数都相同的话,这两个字符串就一定是变位词
具体做法
为每个词设置一个26位的计数器,先检查每个词,在计数器中设定好每个字母出现的次数
计数完成后,进入比较阶段,看两个字符串的计数器是否相同,如果相同则输出是变位词的结论
def anagramSolution4(s1,s2):c1 = [0] * 26c2 = [0] * 26#分别都计数for i in range(len(s1)):pos = ord(s1[i])-ord('a')c1[pos] = c1[pos] + 1for i in range(len(s2)):pos = ord(s2[i])-ord('a')c2[pos] = c2[pos] + 1j = 0stillOK = True#计数器比较while j < 26 and stillOK:if c1[j] == c2[j]:j = j + 1else:stillOK = Falsereturn stillOK
print(anagramSolution4('apple','pleap'))
值得学习的:计数器的设置
总操作次数T(n)=2n+26,数量级O(n)
本算法依赖于两个长度为26的计数器列表,来保存字符计数,这需要更多的存储空间
时间空间之间的取舍和权衡
Python数据类型的性能
列表list和字典dict操作对比
例如:
4种生成前n个整数列表的方法计时
#首先是循环连接列表(+)方式生成
def test1():l = []for i in range(1000):l = l + [i]
#然后是用append方法添加元素生成
def test2():l = []for i in range(1000):l.append(i)
#接着用列表推导式来做
def test3():l = [i for i in range(1000)]
#最后是range函数调用转成列表
def test4():l = list(range(1000))
from timeit import Timer
t1 = Timer("test1()","from __main__ import test1")
print("concat %f seconds\n" %t1.timeit(number=1000))t2 = Timer("test2()","from __main__ import test2")
print("append %f seconds\n" % t2.timeit(number=1000))t3 = Timer("test3()","from __main__ import test3")
print("comprehension %f seconds\n" % t3.timeit(number=1000))t4 = Timer("test4()","from __main__ import test4")
print("list range %f seconds\n" % t4.timeit(number=1000))
列表连接(concat)最慢,List range最快,速度相差近200倍
是append两倍的样子
值得了解:timeit
创建一个Timer对象,指定需要反复运行的语句和需要运行一次的“安装语句”,然后调用这个对象的timeit方法,其中可以指定反复运行多少次
List基本操作的大O数量级
例如:
list.pop的计时试验
从中部移除元素,要把移除元素后面的元素全部向前挪位复制一遍。这种实现方法能够保证列表按索引取值和赋值的操作很快,达到O(1)
import timeit
popzero = timeit.Timer("x.pop(0)","from __main__ import x")
popend = timeit.Timer("x.pop()","from __main__ import x")
print("pop(0) pop()")
for i in range(1000000,100000001,1000000):x = list(range(i))pt = popend.timeit(number=1000)x = list(range(i))pz = popzero.timeit(number=1000)print("%15.5f, %15.5f"%(pz,pt))
将实验数据画成图表
pop()是平坦的常数,pop(0)
是线性增长的趋势
dict数据类型
根据关键码(key)找到数据项,二列表是根据位置(index)
最常用的取值get和赋值set,contains(in)判断字典中是否存在某个关键码(key),性能为O(1)
例如,
list和dict的in操作对比
import timeit
import random
for i in range(10000,1000001,20000):t = timeit.Timer("random.randrange(%d) in x"%i,"from __main__ import random,x")x = list(range(1))lst_time = t.timeit(number=1000)x = {j:None for j in range(i)}#数据是None,key来自于range(i)d_time = t.timeit(number=1000)print("%d,%10.3f,%10.3f"%(i,lst_time,d_time))
值得学习的:x = {j:None for j in range(i)}
字典的执行时间与规模无关,是常数
列表的执行时间则随着列表的规模加大而线性上升
1算法分析——数据结构与算法Python版学习笔记相关推荐
- 数据结构与算法Python版MOOC笔记及练习【七】
文章目录 什么是顺序查找 算法分析 二分查找 冒泡算法思路 插入排序 谢尔排序 归并排序 快速排序 课程练习 什么是顺序查找 数据项保存在像列表这样的集合中,我们会称这些数据项具有线性或者顺序关系. ...
- mooc数据结构与算法python版第十一周作业_中国大学 MOOC_数据结构与算法Python版_2020最新答案学习指南...
中国大学 MOOC_数据结构与算法Python版_2020最新答案学习指南 更多相关问题 [判断题]实际集成运放的上限截止频率为无穷大 [多选题]现代城市的发展凸现出与以往不同的动力机制包括 教师在引 ...
- 陈斌老师《数据结构与算法Python版》第五周作业——ASCII谢尔宾斯基地毯
陈斌老师<数据结构与算法Python版>第五周作业--ASCII谢尔宾斯基地毯 题目 思路 程序如下 总结 题目 谢尔宾斯基地毯是形如上图的正方形分形图案,每个地毯可分为等大小的9份,其中 ...
- mooc数据结构与算法python版期末测验_中国大学MOOC(慕课)_数据结构与算法Python版_测试题及答案...
中国大学MOOC(慕课)_数据结构与算法Python版_测试题及答案 更多相关问题 采用fopen()函数打开文件,支持文件读取的参数有: [简答题]简单阐述高分子材料热-机械特征及成型加工的关系,并 ...
- mooc数据结构与算法python版期末考试_数据结构与算法Python版-中国大学mooc-试题题目及答案...
数据结构与算法Python版-中国大学mooc-试题题目及答案 更多相关问题 婴儿出生一两天后就有笑的反应,这种笑的反应属于(). [判断题]填制原始凭证,汉字大写金额数字一律用正楷或草书书写,汉字大 ...
- python数据结构算法 北京大学_北京大学公开课《数据结构与算法Python版》
之前我分享过一个数据结构与算法的课程,很多小伙伴私信我问有没有Python版. 看了一些公开课后,今天特向大家推荐北京大学的这门课程:<数据结构与算法Python版>. 课程概述 很多同学 ...
- 数据结构与算法 python版 之 递归三定律
#数据结构与算法 python版 之 谢尔宾斯基三角形 , 树叉 1.为了向阿西莫夫的"机器人三定律"直径,递归算法也总结出"三定律" 1递归算法必须有一个基本 ...
- 数据结构python版 答案,中国大学 MOOC_数据结构与算法Python版_章节测验答案
中国大学 MOOC_数据结构与算法Python版_章节测验答案 更多相关问题 认识的本质是()A.肯定世界是可知的B.主体对客体的能动反映C.主体对客体的直观反映D.实践是 水灰比是影响混凝土()的主 ...
- 数据结构与算法python版 MOOC 第九周
九.树及算法-上 本系列博客基于" (北京大学)数据结构与算法python版"慕课,课程在中国大学慕课和bilibili上均可找到. 1. 内容 树结构的相关术语 树的表示方法:嵌 ...
最新文章
- RxPermissions的简单应用
- JAVA自学笔记07
- 没抢到欧冠杯的票?没关系!在VR中看!
- python中两个矩阵之间的点乘_Python基础--数据分析库--Numpy
- PHP Date()函数详细参数
- 我为什么还要造轮子?欠踹?Monk.UI表单美化插件诞生记!
- 3.1 Tensorflow: 批标准化(Batch Normalization)
- LeetCode 110 Balanced Binary Tree 平衡二叉树
- shell模拟php多进程从redis获取数据
- react事件处理函数中绑定this的bind()函数
- 程序固化到优盘中_将Windows 8/10 系统装进优盘
- [React] 尚硅谷 -- 学习笔记(一)
- seo按天扣费系统_网站seo优化多少钱,SEO快速排名按天扣费怎么样
- solr简介——(九)
- Java学习笔记(13)——Java注释
- 20款优秀的可以替代桌面软件的Web应用(转载自JavaEye)
- keil4.72添加GD32F10x芯片
- 同步发电机励磁调节实验原理_【每日一学】同步发电机的运动方程
- Lucene系列:番外篇-DocValues
- 西门子1200控制V90伺服,西门子1200通过PN通讯控制 V90伺服,程序控制采用FB285功能块