由N个人围圈,报数3的离队问题,分析Python代码的执行效率

问题如题:N个人围城一圈报数(1/2/3/1/2/3/...),数到3的退出队列,求最后留下的人

#-*- coding:UTF-8 -*-
import time

def func1(n):
    """思路:删除原有列表中的凡是数到3及倍数的
    使用临时序列存储要删除的数字,在每次循环完后删除需要去掉的数字"""
    ltPserion = list(range(1,n+1))
    pos = 0
    while len(ltPserion)>1:
        ltRemove = []
        for i in ltPserion:
            pos += 1
            if pos%3==0:
                ltRemove.append(i)
        #print('ltPserion:',ltPserion,'将删除',ltRemove)
        for i in ltRemove:
            ltPserion.remove(i)
    return ltPserion[0]
def func2(n):
    """思路:列表中凡是数到3及倍数
    对于报数进行取余判断,如果是3的倍数就删除"""
    ltPserion = list(range(1,n+1))
    SayNo = 0
    DelCount = 0
    while DelCount1:
        SayNo += 1
        #print(ltPserion, '索引i=',i ,'当前数数SayNo=', SayNo, '人', ltPserion[i], end='')
        if SayNo%3 == 0:
            #print('删除',ltPserion[i], end='')
            ltPserion.remove(ltPserion[i])
            i-=1
        i+=1
        if i>=len(ltPserion):
            i=0
        #print()
    return ltPserion[0]

def func4(n):
    """思路:列表中凡是数到3的就标记为删除
       不用%取余,直接用if判断大于3就从1开始数数"""
    ltPserion = list(range(1,n+1))
    SayNo = 0
    DelCount = 0
    while DelCount

 执行结果如下

>>> 
func1: 92620 39.25819919960245
func2: 92620 0.31389559593181104
func3: 92620 42.987894393368286
func4: 92620 0.30714721310604887
>>> 

分析: 

对于上面的问题,采用了4个方法处理,求得的结果是方法4效率最高。

func1和func3类似,都是处理的list,删除报数为3的人,而func3更慢一点的原因是“if i>=len(ltPserion):”每次循环都获取了一次人员列表的长度。

func2和func4都没有删除数到3的人,只是在原队列中标记了去除的人,效率高了100倍,有此可见,程序执行循环耗费的时间,比队列的元素的删除省不少运行时间。func4比func2效率高一点点的原因是func2中“if SayNo%3==0:”使用了取余,取余操作的效率不如“if SayNo==3:SayNo = 1; else: SayNo += 1;”效率高。

当然func2、func4比起func1、func3也有弊端,就是占用的内存,func1、func3运行内存会不断的减小,而func2、func4不会减小。

你可能感兴趣的:(Python)