文章目录

  • 1.什么是算法分析?
  • 2.大O表示法
  • 3.变位词的判断问题
  • 4. Python数据类型的性能

1.什么是算法分析?

如何对比两个程序?

  • 好的程序变量名清晰,无用垃圾代码少。
  • 代码风格,可读性

程序和算法的区别

  • 算法是对问题解决的分步描述
  • 程序则是采用某种编程语言实现的算法

算法分析的概念

  • 算法分析主要就是从计算资源消耗的角度来评判和比较算法。更高效利用计算资源,或者更少占用计算资源的算法,就是好算法。

那么何为计算资源?

  • 一种是算法解决问题过程中需要的存储空间或内存
  • 另一种是算法的执行时间

运行时间检测

  • 获取打印111所需时间
import time
start = time.time()
print(111)
end = time.time()
running_time = end-start
print('time cost : %.5f sec' %running_time)

运行结果

111
time cost : 0.00000 sec
  • 显示时间是0.00000秒,是因为打印111所需要的时间太短了,所以不是很精确。

如何比较算法的“好坏”?

  • 衡量算法可从时间空间两个角度分析

有两个不同的算法,都可以计算前n项数的和。

①迭代算法

import time
def sumOfN2(n) :start = time. time( )theSum = 0for i in range(1,n+1):theSum = theSum + iend = time. time( )return theSum, end-start
print("Sum is %d required %10.7f seconds"% sumOfN2 (10000) )
sum is 50005000 requires 0.0007980 seconds

②无迭代算法

import time
def sumOfN3(n) :start = time. time( )theSum=(n*(n+- 1))/2end =time. time( )return theSum ,end-start
sum is 50005000 requires 0.0000010 seconds

第二种算法所需时间更短

观察一下第一种迭代算法

  • 包含了一个循环,可能会执行更多语句 这个循环运行次数跟累加值n有关系,n增加,循环次数也增加,执行时间增加
import time
def sumOfN2(n) :theSum = 0for i in range(1,n+1):#就是这条循环语句!!theSum = theSum + ireturn theSum

2.大O表示法

赋值语句 是作为算法时间的度量指标

  • 赋值语句执行少,则程序运行时间短。

如何来看赋值语句执行的次数呢?

  • 在这个程序中,我们用T(n)来表示赋值语句的条数
def sumOfN2(n) :theSum = 0  #一条赋值语句,T(n)1=1for i in range(1,n+1):#一条循环语句,循环了n次T(n)2=n theSum = theSum +i#一条赋值语句,T(n)2=n*1return theSum

所以对于"问题规模"n,赋值语句数量
T(n)=T(n)1+T(n)2=n+1

什么是问题规模

  • 问题规模就是影响算法执行时间最主要的因素。
  • 所以对于上面那个程序,前1000个整数求和,对比前100个整数求和,算是较大的问题规模,所以前n个整数累计求和,n就是问题规模了

算法分析目标?

  • 算法分析的目标是找出问题规模会怎样影响算法执行时间

数量级函数

  • 数量级函数就是用来描述T(n)中随着n增加增加速度最快的主导部分,称作“大O”表示法,记作O(f(n)),其中f(n)表示T(n)中的主导部分

主导部分怎么确定呢?就是T(n)中增长速度最快的部分
T(n)=n+1,主导部分是n
T(n)=200n3+20n+1000,主导部分是n3

影响算法运行时间的因素不只有问题规模,还有其他。

常见的大O数量级函数

f(n) 名称
1 常数
log(n) 对数
n 线性
n*log(n) 对数线性
n2 平方
n3 立方
2n 指数

从代码分析执行时间数量级函数

a=5
b=6
c = 10  #3条赋值语句,所以T(n)1=3
for i in range(n):  #循环语句nfor j in range(n):  #循环语句n,所以T(n)2=n的平方X=i*iY=j*jZ=i*1    #三条赋值语句,所以T(n)2=3n的平方
for k in range(n):#循环语句n,T(n)3=nW =a*k+45V=b*b   #两条赋值语句,所以T(n)3=2n
d=33   #1条赋值语句,所以T(n)4=1

所以,T(n)=T(n)1+T(n)2+T(n)3+T(n)4=3+3n2+2n+1=3n2+2n+4

其它算法复杂度表示法

  • 大O表示法
    表示了所有上限中最小的那个,上限。
  • 大Ω表示法
    表示了所有下限中最大的那个下限
    f(n) = Ω(g(n))当且仅当g(n) = o(f(n))
  • 大θ表示法
    如果上下限相同,那么就可以用大θ表示 f(n) =θ(g(n)) 当且仅当f(n) = O(g(n))且f(n) = Ω(g(n))

3.变位词的判断问题

  • 所谓“变位词”是指两个词之间存在组成字母的重新排列关系。如:heart和earth,python和typhon
  • 可以很好展示同一问题的不同数量级算法

写一个bool函数,以两个词作 为参数,返回这两个词是否变位词

解法1:逐字检查

  • 思路:将词1中的字符逐个到词2中检查是否存在,存在的字符“打勾”标记,如果每个字符都能找到,则两个词是变位词 。
  • 将词2对应“打勾”的字符设为None。由于字符串是不可变类型,需要先复制到列表中:
def anagramSolution(s1,s2):alist = list(s2) #复制s2到列表stillOK = Truepos1 = 0while 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 stillOK
print(anagramSolution("abcd","dcba"))
  • 问题规模:词中包含的字符个数n
  • 主要部分在于两重循环:
    外层循环遍历s1每个字符,将内层循环执行n次
    而内层循环在s2中查找字符,每个字符的对比次数,分别是1、2…n中的一个,而且各不相同
  • 所以总执行次数是1+2+3+…+n,可知数量级O(n2)

解法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 + 1elsematches = Falsereturn matches
  • 粗看上去,本算法只有一个循环,最多执 行n次,数量级是O(n)
    但循环前面的两个sort并不是无代价的,如果查询下后面的章节,会发现排序算法采用不同的解决方案,其运行时间数量级差不多是 O ( n2 ) 或者O(n log n),大过循环的O(n).
  • 所以本算法时间主导的步骤是排序步骤
  • 本算法的运行时间数量级就等于排序过程的数量级O(n log n)

解法3:暴力法

  • 暴力法解题思路为:穷尽所有可能组合
  • 将s1中出现的字符进行全排列,再查看s2是否出现在全排列列表中
  • n个字符全排列,是n!个字符,例如,对于20个字符长的词来说,将产生 20!=2,432,902,008,176,640,000个候选词,如果每微秒处理1个候选词的话,需要近8万年时间来做完所有的匹配。所以我们就不用这个算法了,它不是个好算法。

解法4.计数比较

  • 若两个字符中每个字母出现次数相同,则为变位词
  • 具体做法:为每个词设置一个26位的计数 器,先检查每个词,在计数器中设定好每 个字母出现的次数,计数完成后,进入比较阶段,看两个字符 串的计数器是否相同,如果相同则输出是 变位词的结论
def anagramSolution4(s1,s2):c1 = [0]*26    #长度为26 全0的列表 代表每个字母出现的次数c2 = [0]*26for i in range(len(s1):pos = ord(s1[i])-ord('a') #ord返回字符的unicode编码 字母的编码是连续的c1[[pos] = c1[pos] + 1for i in range(len(s2):pos = ord(s2[i])-ord('a') #ord返回字符的unicode编码 字母的编码是连续的c2[[pos] = c2[pos] + 1j = 0stillOK = Truewhile j<26 and stillOK:#计数器比较if(c1[j]==c2[j]):j = j + 1else:stillOK = Falsereturn stillOK
  • 前两个循环用于对字符串进行计数,操作次数等 于字符串长度n;第3个循环用于计数器比较,操作次数总是26次.
    所以总操作次数T(n)=2n+26,其数量级为O(n)
    这是一个线性数量级的算法,是4个变位词判断算法中性能最优的
  • 本算法依赖于两个长度为26的计数器列表,来保存字符计数,这相比前3个算法需要更多的存储空间.(牺牲空间换时间)

4. Python数据类型的性能

  • list和dict的常见操作

  • list基本操作的大O数量级
  • dict数据类型大O数量级
  • 字典的执行时间与规模无关,是常数O(1)
    而列表的执行时间则随着列表的规模加大,呈线性上升 O(n)

算法分析(python)相关推荐

  1. 资料分享:送你一本《数据结构与算法:Python语言描述》电子书!

    下图为 TIOBE 3月编程语言排行榜. 从榜单来看,曾经铁打的 Java.C.C++ 局势,早已在数月前被 Python 的闯入而打破.究其根由,并非是 C++ 的应用领域正在逐渐缩减,而是随着人工 ...

  2. js rsa解密中文乱码_建议收藏 | 最全的 JS 逆向入门教程合集

    点击上方"咸鱼学Python",选择"加为星标" 第一时间关注Python技术干货! 嘿,大家好,截止今天咸鱼零零散散分享爬虫.数据分析基础和 Web 的内容已 ...

  3. js滚动条下拉一定值_JS逆向 | 无限Debugger之淘大象

    置顶公众号 今天继续和大家研究JS逆向,不少小伙伴在JS逆向的时候遇到过无限debugger的反爬,今天就拿一个网站练练手感受下无限debugger. 分析请求 先打开这次的目标网站--淘大象(htt ...

  4. 人工智能课程实训方案

    第一章 发展背景 当今,世界无时无刻不在发生着变化.对于技术领域而言,普遍存在的一个巨大变化就是为大数据(Big data)打开了大门.随着国家大数据战略推进实施以及配套政策的贯彻落实,大数据产业发展 ...

  5. 京东APP中Flutter探索及优化

    点击"开发者技术前线",选择"星标" 让一部分开发者先看到未来 前言 随着Flutter稳定版本逐步迭代更新,京东APP内部的Flutter业务也日益增多,Fl ...

  6. AI教学实训整体解决方案

    第一章 发展背景 当今,世界无时无刻不在发生着变化.对于技术领域而言,普遍存在的一个巨大变化就是为大数据(Big data)打开了大门.随着国家大数据战略推进实施以及配套政策的贯彻落实,大数据产业发展 ...

  7. 高校人工智能专业实训建设方案

    第一章 发展背景 当今,世界无时无刻不在发生着变化.对于技术领域而言,普遍存在的一个巨大变化就是为大数据(Big data)打开了大门.随着国家大数据战略推进实施以及配套政策的贯彻落实,大数据产业发展 ...

  8. python数据结构与算法分析_数据结构与算法(Python版)

    为什么研究数据结构与算法 本周带大家进入Python版数据结构与算法的学习.想必大家都听过"算法"一词,算法的学习对编程者来说是至关重要的.首先我们先了解一下为什么要研究数据结构与 ...

  9. 【python数据挖掘课程】二十.KNN最近邻分类算法分析详解及平衡秤TXT数据集读取

    这是<Python数据挖掘课程>系列文章,也是我这学期上课的部分内容及书籍的一个案例.本文主要讲述KNN最近邻分类算法.简单实现分析平衡秤数据集,希望这篇文章对大家有所帮助,同时提供些思路 ...

  10. python高斯求和_二、算法分析

    一.什么是算法分析 程序和算法的区别: 算法是对问题解决的分步描述 程序是采用某种编程语言实现的算法,同一个算法通过不同的程序员采用不同的编程语言,能产生很多程序 算法分析的概念: 算法分析主要就是从 ...

最新文章

  1. 2020年AI将会如何发展?吴恩达、周志华、Yann LeCun等大神对2020年 AI 发展趋势的预测的预测...
  2. 持久对象生命周期的状态
  3. tmadmin: command not found和tmadmin: error while loading shared libraries: libgpnet.so
  4. STL 源代码分析 算法 stl_algo.h -- includes
  5. 新媒体运营工具大盘点,收藏方便不备之需!
  6. C++中数据类型int, short, long, long long的数据范围
  7. 二极管整流和同步整流区别
  8. Java计算某年某月天数_编程计算某年某月某日是该年的第多少天。例如:2016年3月2日是2016的 第62 天。(java)...
  9. JVM:垃圾收集器与内存分配策略
  10. 程序linux培训,马哥-51CTO-Linux培训-0910-程序包管理
  11. 2021,OpenSquare回顾过去,展望未来
  12. 小学教师听课体会 计算机,小学教师观有效课堂听课心得体会
  13. 数据中心的等级 数据中心的分层
  14. 电脑使用DP线连接显示器,插在显示器音频口的音响没有声音解决办法
  15. 《C++面向对象程序设计》董正言、张聪版内容概括
  16. 看门狗电路 通俗理解
  17. IIR数字滤波器设计---双线性变换法
  18. echarts绘制四川地图
  19. spark (3)Spark Standalone集群安装介绍
  20. 国,省,市,区(县)(四级联动)

热门文章

  1. 空气过滤器过滤效率如何计算
  2. 忆恩师周伯勋先生讲群论的情景
  3. Python交互界面实现自由换行
  4. adb:win10系统下安装
  5. Windows系统下搭建MPI(并行计算)环境
  6. 小白学算法——借用leetcode(其实就是刷题记录....——1
  7. 数据结构与算法基础-学习-19-哈夫曼解码
  8. C++的二分查找函数
  9. 方差分析——联立区间估计
  10. 【设计模式学习笔记】1:认识六大设计原则(OCP,LSV,DIP,ISP,LKP,SRP)