Python算法分析(一)

一、概念

        算法分析关心的是基于所使用的计算资源比较算法。

        即我们总是希望用更少的计算资源得到同样的结果,而这里的计算资源有空间上的使用、时间上的使用、代码可读性等。

二、大O记法

        对于一个函数,其时间函数T\left ( n \right )可以估计为其基本语句的执行次数,参数n被称为问题规模。

        常见的大O函数有:1(常数)、logn(对数)、n(线性)、nlogn(对数线性)、n^{2}(平方)、n^{^{3}}(立方)、2^{n}(指数)。

        一般来说,谁在T(n)中起主导作用,就记为O(n)

示例:

        异序值检测:如果一个字符串只是重 排了另一个字符串的字符,那么这个字符串就是另一个的异序词,比如 heart 与 earth,以及 python 与 typhon。为了简化问题,假设要检查的两个字符串长度相同,并且都是由 26 个英文字母的小写 形式组成的。我们的目标是编写一个布尔函数,它接受两个字符串,并能判断它们是否为异序词。

        1、清点法
def anagramSolution1(s1, s2):
    alist = list(s2)
    pos1 = 0
    stillOK = True

    while pos1 < len(s1) and stillOK:
        pos2 = 0
        found = False
        while pos2 < len(alist) and not found:
            if s1[pos1] == alist[pos2]:
                found = True
            else:
                pos2 = pos2 + 1

        if found:
            alist[pos2] = None
        else:
            stillOK = False

        pos1 = pos1 + 1

    return stillOK

        对于上述算法,每检查一个s1中的字符,都需要遍历s2中所有字符。其时间函数T(n)可以表示为:\sum_{i=1}^{n}i=\frac{n(n+1)}{2}=\frac{1}{2}n^{2}+\frac{1}{2}n,在这个公式中n^{2}起着决定性作用,因此我们可以记作O(n^{2})

        2、排序法
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

        上述代码通过对两个字符串进行排序再检查对应位置的字符是否相同来判断是否为异序词(其实有个漏洞,就是这里是默认两个字符串就是不一样的,如果是两个本来就相同的词,用此办法得出其就是异序词,实际上不是)。

        乍一看,该算法的时间复杂度为O(n),实际上,我们所调用的sort()方法是有代价的,其时间复杂度基本在O(n^{2})O(nlogn),也就是说,该算法的起决定性作用的是排序的时间复杂度。

        3、蛮力法

        蛮力法即穷尽所有的可能性,这里示例用蛮力法可以将s1中的字符生成所有可能的字符串再进行比对,26个字符串有n!种可能性,效率太低。

        4、计数法
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

        该算法是将两个字符串ASCLL码值通过哈希表的形式存储下来,再去找对应的索引(值得注意的是,可能会有重复的字符出现,所以要对c1和c2进行+1操作)。

        其时间复杂度函数T(n)=2n+26

三、Python数据结构的性能

        本章会对Python语言中的列表和字典进行损耗和收益分析,主要理解Python数据结构的效率。

        1、列表

        列表的常见操作有:索引、赋值以及加长列表。

        一些实例会助于我们的理解:

        这是四种生成数组的方式:

def test1(): 
    l = [] 
    for i in range(1000): 
        l = l + [i] 

def test2(): 
    l = [] 
    for i in range(1000): 
        l.append(i) 

def test3(): 
    l = [i for i in range(1000)] 

def test4(): 
    l = list(range(1000))

        使用time模块可以记录各个生成方式所花费的时间成本。通过观察我们可以得知第二种追加方式远快于第一种连接操作,而后面两种列表构造器range比追加方式更快了至少一倍。

        下图是一些列表操作的大O效率:

        2、字典

        字典的常见操作有:取值、赋值以及包含(检查某个键是否在字典中)。

        下图是字典操作的大O效率:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值