|
|
发表于 2017-2-9 15:31:02
|
显示全部楼层
其实我们可以采用python的timeit对2种代码进行简单的评估
我们首先写2个函数,分别实现2种方案
- In [1]: def foo1(a,b):
- ...: for n in range(a,b):
- ...: if n == (n//100)**3+((n//10)%10)**3+(n%10)**3 :
- ...: print(n)
- ...:
- In [2]: def foo2(a,b):
- ...: for n in range(a,b):
- ...: sum1 = 0
- ...: tmp = n
- ...: while tmp:
- ...: sum1 += (tmp%10)**3
- ...: tmp //= 10
- ...: if sum1 == n:
- ...: print(n)
- ...:
- In [3]: foo1(100,1000)
- 153
- 370
- 371
- 407
- In [4]: foo2(100,1000)
- 153
- 370
- 371
- 407
复制代码
好的,函数准备好了,接下来我们调用timeit看一下需要多少时间
- In [5]: %timeit foo1(100,1000)
- 1000 loops, best of 3: 1.97 ms per loop
- In [6]: %timeit foo2(100,1000)
- 1000 loops, best of 3: 2.2 ms per loop
复制代码
单次测试1000个循环,共3次测试,foo1()大约比foo2()快了那么0.3ms,那么foo1()是否比foo2()好呢?
在这个简单的问题中,答案是肯定的。因为根据算法的时间复杂度来说,foo1()的时间复杂度为O(n),而foo2()的时间复杂度为O(kn),k为位数,此处k=3。理论上我们不会特别关心k的大小,将O(kn)视为O(n),而当k接近n大小时(假设我们要查找10^100 ~ 10^100+1000内水仙花数!),问题的复杂度会上升为O(n^2)。
当然,这时候不可能采用foo1()这样的写法,手工将各个位数拆开来。因此,只能说在这个特定的问题中,foo1()还是比较取巧的。
编程中有句话叫:Keep your code dry! 意思就是你的代码要简练!不要去做那些吃力重复的劳动,foo1()虽然看起来行数较少,但事实上表达式难以让人一下子理解,并且有重复劳动之嫌,试想一下如果要求1~1,000,000内的水仙花数,你还要这么写么?? |
评分
-
查看全部评分
|