【问题标题】:Need Help! Count Primes using python需要帮忙!使用python计算素数
【发布时间】:2025-12-28 19:35:11
【问题描述】:

计算小于非负数 n 的素数个数。我创建了以下代码,但复杂性太高。如果有人给我一个更好的解决方案,我将不胜感激。

import math
class Solution(object):
    def countPrimes(self, n):
        PrimeCount=0
        primelist=[]
        for i in range(2,n):
            if self.primeCheck1(i,primelist)==True:
                primelist.append(i)       #try2 with new logic
                PrimeCount=PrimeCount+1

        return PrimeCount



    def primeCheck1(self,n,primelist):
        flag=False
        if n==2:
            return True
        elif n==3:
            return True
        sqroot=int(math.sqrt(n))

        for j in range(0,sqroot):
            if n%primelist[j]==0:
                flag=True
                break

        if flag!=True:
            return True
        else:
            return False

【问题讨论】:

标签: python algorithm numbers time-complexity primes


【解决方案1】:

我喜欢您构建素数列表并使用该列表检测更大素数的方式。你是对的,你的代码比它需要的更复杂,特别是你的 flag 变量是不需要的。

您在primeCheck1() 方法中也遗漏了一些可以加快处理速度的技巧。由于我的 Python 不存在,因此这是类似 Python 的伪代码。我假设您将能够转换它。

def primeCheck1(self, n, primelist):

  # Handle even numbers.
  if n % 2 == 0:
        # The only even prime is 2.
        return (n == 2)

  # Handle multiples of 3.
  if n % 3 == 0:
        return (n == 3)

  # Handle remaining numbers.
  sqroot = int(math.sqrt(n))

  for j in range(0, sqroot):
    if n % primelist[j] == 0:
      return False  # Not a prime number.

  # If we get this far then the number is prime.
  return True

end primeCheck1

在一个小问题上,你有一个不间隔代码的习惯:a==b 而不是a == b。使用空格作为分隔符使代码更易于阅读。

【讨论】:

    【解决方案2】:

    对您的代码进行返工,计算出少于一百万个素数的情况下,它的速度提高了 3 倍:

    class Solution(object):
        def countPrimes(self, n):
            primelist = []
    
            for i in range(2, n):
                if self.primeCheck(i, primelist):
                    primelist.append(i)
    
            return len(primelist)
    
        def primeCheck(self, n, primes):
    
            if n < 2:
                return False
    
            if n % 2 == 0:  # 2 is the only even prime
                return n == 2
    
            for prime in primes:
    
                if prime * prime > n:  # easier to square many than sqroot one
                    return True
    
                if n % prime == 0:  # divisible by a prime, not a prime
                    return False
    
            return True
    
    solution = Solution()
    
    print(solution.countPrimes(1000000))
    

    这包括@rossum 向您指出的一些技巧。

    但是,我们可以做得更好。这是使用 @ClockSlave's prime sieve code 重新实现的方法,计算少于一百万的素数时,它比原来的速度快 22 倍:

    class Solution(object):
    
        def __init__(self):
            self.sieve = None
    
        def countPrimes(self, n):
    
            self.sieve = [True] * n
    
            if n > 0:
                self.sieve[0] = False
                if n > 1:
                    self.sieve[1] = False
    
            def mark_sieve(prime):
                for index in range(prime + prime, n, prime):
                    self.sieve[index] = False
    
            for number in range(2, int(n ** 0.5) + 1):
                if self.sieve[number]:
                    mark_sieve(number)
    
            return sum(self.sieve)
    
    solution = Solution()
    
    print(solution.countPrimes(1000000))
    

    这里的胜利是消除所有那些昂贵的部门。

    【讨论】:

      【解决方案3】:

      首先使用pip install sympy 安装sympy 包。然后试试这个:

      import sympy
      PrimeCount=0
      n=int(input("Number?"))
      for elem in range(n):
         if sympy.isPrime(elem):
            PrimeCount+=1
      print(PrimeCount)
      

      【讨论】:

      • 我很确定 OP 必须为学校做这件事。所以使用sympy 会破坏任务的全部目的。
      • 另外,Python 中没有 ++ 运算符。您需要改用+= 1
      • 哎呀,使用 java 有一段时间了。修复它
      【解决方案4】:

      您可以使用按位筛选算法。

      SIZE = 1000000
      LIMIT=int(math.sqrt(SIZE)+1)
      
      prime = []
      
      def sieve():
          for i in range(SIZE/32):
              prime[i]=0xffff
              prime[0]&=~(1<<(1%32))
      
          for i in range(LIMIT+1):
              if(prime[i/32]&(1<<(i%32))):
                  for j in range(2*i, SIZE, j=j+i):
                      prime[j/32]&=~(1<<(j%32))
      
      def isPrime(n):
              return prime[n/32]&(1<<(n%32))
      

      【讨论】:

      • 你,或者投票赞成这个的人,真的尝试过运行它吗?首先,它似乎没有计算素数的数量,只是生成素数。其次,它似乎不是可运行的 Python,例如def isPrime(int n):range(2*i, SIZE, j=j+i)
      • 我只是给他看一个降低时间复杂度的代码示例
      【解决方案5】:
      def count_primes(prime):
      
          check=2
          main_res=0
      
          while check <= prime:
              result=0
              control=1
              while control <= check: 
                  if check%control==0:
                      result+=1
                      control+=1
                  else:
                      control+=1
              if result==2:
                  main_res+=1
      
      
              check+=1
      
          return main_res
      
      
      # Test for COUNT PRIME
      #print(count_primes(100))
      

      【讨论】:

      • 问题是寻找更复杂的素数。您发布的代码虽然有效,但复杂度并不高。