【问题标题】:Python Prime Number GeneratorPython素数生成器
【发布时间】:2015-05-09 18:35:22
【问题描述】:

代码将每个非素数打印两次,但素数只打印一次。 但是,我只想打印素数。 我知道素数生成器有更好的解决方案,但我真的很想知道这段代码的错误在哪里。

prime_numbers = []

def prime_gen(upper_limit):
    for i in range(2, upper_limit):
        for j in range(2, upper_limit):
            if i % j == 0 and i % j != 1 and i % j != j and i:
                prime_numbers.append(i)
prime_gen(20)
print(prime_numbers)

【问题讨论】:

    标签: python


    【解决方案1】:

    您应该将j 停止在i,而不是上限。没有必要寻找大于 ii 的除数 - 没有。并且i 本身不应该被测试,因为它总是分裂自己。

    而且一个数不是素数,因为它可以被另一个整除,而是因为它不是。所以测试所有个可能的除数,只有在最后,如果没有找到,只有在素数列表中添加i

    prime_numbers = []
    
    def prime_gen(upper_limit):
        for i in range(2, upper_limit):
            for j in range(2, i):             # <== only look for divisors less than i
                if i % j == 0:                # <== STOP if you found a divisor
                    break
            else:                             # <== Add only if no divisor was found
                prime_numbers.append(i)
    prime_gen(20)
    print(prime_numbers)
    

    【讨论】:

      【解决方案2】:
       prime_numbers = [2] # we know two is prime
       def prime_gen(upper_limit):
          # start at 3 and use a step of 2
          for i in range(3, upper_limit, 2):
              # loop from 2 to i
              for j in range(2, i):
                  # if i was divisible by any j we will break the loop
                  # as i is not prime
                  if i % j == 0:
                      break
              else:
                  # if we get here we completed our inner loop
                  # which means no i % j was equal to 0
                  prime_numbers.append(i)
      

      你需要内部循环从 2 到 i,你不想要满足 if i % j == 0 的数字,因为它们不是素数。你最后的and i 也总是为真,任何不是0 的数字都将为真,因此测试是多余的。您也可以从 3 开始并使用 2 步长,所有偶数都不能是素数。

      您还可以将if/else 替换为any:,如果我们找到任何等于0 的i % j,它将延迟评估和中断。

      prime_numbers = [2]
      
      def prime_gen(upper_limit):
          for i in range(3, upper_limit, 2):
              if not any(i % j == 0 for j in range(2, i)):
                  prime_numbers.append(i)
      

      【讨论】:

      【解决方案3】:

      第一个没有优化,而第二个稍微优化了一些。当然,“Sieve of Eratosthenes”是最好的。此函数按顺序生成素数,但没有上限。

      简单且未优化:

      def simple_prime_list(num):
          list_of_prime = (2, )
          current_num = 2
          is_prime = True
          while len(list_of_prime) != num:
              current_num += 1
              for i in list_of_prime:
                  if current_num % i == 0:
                      is_prime = False
              if is_prime == True:
                  list_of_prime += (current_num,)
              #To reset the status
              is_prime = True
          return list_of_prime
      

      通过在数字不是素数时不检查所有偶数和break 进行轻微优化:

      def prime_list(num):
          list_of_prime = (2, )
          current_num = 2
          is_prime = True
          while len(list_of_prime) != num:
              current_num += 1
              if current_num % 2 != 0:
                  for i in list_of_prime:
                      if current_num % i == 0:
                          is_prime = False
                          break
                  if is_prime == True:
                      list_of_prime += (current_num, )
              #To reset the status
              is_prime = True
          return list_of_prime
      

      尝试测量 2 个不同的运行时间:

      import time
      def measureTime(fn):
          start = time.clock()
          fn()
          end = time.clock()
          #return value in millisecond
          return (end - start)*1000
      
      print('Simple Prime List:', measureTime(lambda: simple_prime_list(1000)), 'ms')
      print('Optimised Prime List:', measureTime(lambda: prime_list(1000)), 'ms')
      

      输出:

      简单素数列表:775.798 毫秒

      优化的 Prime 列表:69.48299999999996 毫秒

      【讨论】:

        【解决方案4】:

        如果你正在寻找生成器,你应该使用 yield 而不是 return,这是我对无限素数生成器的回答:

        def primes_generator():
            n = 1
            while True:
                for x in range(2, n): 
                    if n % x == 0:
                        #not prime
                        break
                else: 
                    #prime
                    yield n #<- yield instead of return to create a generator
                n+=1
        

        如果你需要一个上限,你可以像这样使用它:

        def primes_generator(upper_limit):
            for n in range(2, upper_limit):
                for x in range(2, n): 
                    if n % x == 0: break
                else: 
                    yield n
        

        那么你可以像这样使用它:

        primes = primes_generator()
        for prime in primes:
            print(i)
        

        【讨论】:

          【解决方案5】:

          简单的python控制台素数生成器

          global num,primes
          num = 1
          primes=[]
          gen = raw_input("enter the number of primes to generate: ")
          
          
          while len(primes)<int(gen)+1:
              if num > 0:
                  for i in range(2, num):
                      if (num % i) == 0:
                          num+=1
                          break
              else:
                  print(primes)
                      primes.append(num)
                      num+=1
          print "Primes generated : ",len(primes)-1
          

          【讨论】:

            猜你喜欢
            • 2013-03-20
            • 2019-09-06
            • 2015-02-20
            • 2013-07-24
            • 1970-01-01
            • 2015-06-30
            • 2012-05-25
            • 2010-10-08
            • 1970-01-01
            相关资源
            最近更新 更多