在Python中计算小于非负数n的素数的数量

时间:2016-01-23 17:57:49

标签: python math time-complexity primes

我正在解决leetcode中的编码问题,其中我们应该计算小于非负数n的素数的数量。

这是我的解决方案:

class Solution(object):

    def isPrime(self, Number):
        return 2 in [Number, 2**Number % Number]

    def countPrimes(self, n):
        """
        :type n: int
        :rtype: int
        """
        count_prime = 0
        prime_range = filter(lambda x: x % 2 != 0 and x % 3 != 0 and x % 5 != 0, xrange(n))

        for i in prime_range:
            if self.isPrime(i):
                count_prime += 1

        return count_prime

print Solution().countPrimes(499979)

虽然这适用于较小的数字,但是对于较大的数字需要花费大量的时间,而且我不确定哪个部分在我的程序中消耗更多的时间?在这里,我只测试大于100的数字。

  

任何人都可以帮我找到哪个部分需要更多时间

2 个答案:

答案 0 :(得分:2)

  

任何人都可以帮我找到哪个部分需要更多时间

为什么 Python可以。简而言之,Python捆绑了cProfile Python代码的分析器。在其下运行模块会产生以下统计信息:

jim@jim: python -m cProfile tt.py 
673
         6311 function calls in 0.016 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.016    0.016 tt.py:1(<module>)
        1    0.000    0.000    0.000    0.000 tt.py:1(Solution)
     4979    0.002    0.000    0.002    0.000 tt.py:12(<lambda>)
     1327    0.013    0.000    0.013    0.000 tt.py:3(isPrime)
        1    0.000    0.000    0.016    0.016 tt.py:6(countPrimes)
        1    0.001    0.001    0.003    0.003 {filter}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

所有这些列are described in the documentation。因此,正如您所看到的,大多数时间实际上花在函数isPrime上:

1327    0.013    0.000    0.013    0.000 tt.py:3(isPrime)

总共1327次来电0.013/0.016次来电C次。所以,好的,这就是问题所在。

现在,在您发现瓶颈所在之后,您可以尝试寻找优化方法。 大多数时候,只需使用更有效的算法以及合适的数据结构,您就可以获得更好的性能。

如果您想快速加快速度,请考虑查看CythonNumba等内容。如果那些没有削减它的人会写一个纯粹的div.position-N扩展名,这可能会更快一些。如果这不能减少,那就放弃吧,因为你对任何事情都不满意。

答案 1 :(得分:0)

你看过eratosthenes筛子了吗?它是寻找素数的经典算法:

  

Eratosthenes的Sieve是一个简单的算法,可以找到一个给定整数的素数。实现此算法,只允许优化外部循环可以在限制的平方根处停止,内部循环可以从刚刚找到的素数的平方开始。这尤其意味着你不应该通过使用预先计算的轮子进行优化,即不要假设你只需要交叉出奇数(基于2的轮子),数字等于1或5模6(轮子基于2和3),或基于低素数的类似轮子。 http://rosettacode.org/wiki/Sieve_of_Eratosthenes

Sieve of Eratosthenes - Finding Primes Python