【问题标题】:Number of primes less than or equal to x小于或等于 x 的素数个数
【发布时间】:2021-11-12 06:54:00
【问题描述】:

π(x) = 素数个数≤x

下面的代码给出了小于或等于 N 的素数个数

它适用于 N

  • 输入 - 输出表

    |    Input    |   Output      | 
    |-------------|---------------|
    | 10          |     4✔       |
    | 100         |     25✔      |
    | 1000        |     168✔     |
    | 10000       |     1229✔    |
    | 100000      |     9592✔    |
    | 1000000     |     78521✘   | 
    

    然而,π(1000000) = 78498

    import time
    def pi(x):
        nums = set(range(3,x+1,2))
        nums.add(2)
        #print(nums)
        prm_lst = set([])
        while nums:
            p = nums.pop()
            prm_lst.add(p)
            nums.difference_update(set(range(p, x+1, p)))
            #print(prm_lst)
        return prm_lst
    
    
    if __name__ == "__main__":
        N = int(input())
        start = time.time()
        print(len(pi(N)))
        end= time.time()
        print(end-start)
    

【问题讨论】:

  • 你在哪里检查素数?怎么查?
  • @AlexPetrosyan nums.difference_update(set(range(p, x+1, p))set(nums) 中删除p 的所有倍数,其中nums 是一组奇数。
  • 好的。尝试添加一些调试prints 以查看大于 100 000 的倍数会发生什么。我怀疑在某些时候某些操作会静默失败。
  • 也许您认为num.pop() 会从集合中移除 smallest 元素,但我不认为这是有保证的。 pop() 的文档说:从集合中删除并返回任意元素。
  • @PresidentJamesK.Polk 谢谢! nums.difference_update(p, x+2*p, p) 现在给出正确答案正确答案。

标签: python python-3.x list math primes


【解决方案1】:

只有当nums.pop() 返回一个素数时,你的代码才是正确的,而只有当nums.pop() 返回集合中最小的元素时,你的代码才是正确的。据我所知,这不能保证是真的。有一个名为 sortedcontainers 的第三方模块提供了一个 SortedSet 类,可用于使您的代码只需很少的更改即可工作。

import time

import sortedcontainers
from operator import neg


def pi(x):
    nums = sortedcontainers.SortedSet(range(3, x + 1, 2), neg)
    nums.add(2)
    # print(nums)
    prm_lst = set([])
    while nums:
        p = nums.pop()
        prm_lst.add(p)
        nums.difference_update(set(range(p, x + 1, p)))
    # print(prm_lst)
    return prm_lst


if __name__ == "__main__":
    N = int(input())
    start = time.time()
    print(len(pi(N)))
    end = time.time()
    print(end - start)

【讨论】:

  • 这绝对是个好人。
【解决方案2】:

您可以从thread 中以最快的方式读取,如下所示,使用n = 1000000 的此功能,我可以正确找到78498 素数。 (我在这个函数里改了一行)

发件人:

return ([2] + [i for i in range(3,n,2) if sieve[i]])

收件人:

return len([2] + [i for i in range(3,n,2) if sieve[i]])

最后:

def primes(n):
    sieve = [True] * n
    for i in range(3,int(n**0.5)+1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)//(2*i)+1)
    return len([2] + [i for i in range(3,n,2) if sieve[i]])

inp =  [10, 100, 1000, 10000, 100000, 1000000]
for i in inp:
    print(f'{i}:{primes(i)}')

输出:

10:4
100:25
1000:168
10000:1229
100000:9592
1000000:78498

【讨论】:

  • 感谢您的精彩回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-30
  • 1970-01-01
  • 2023-02-23
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多