【问题标题】:Fastest way of testing if a number is prime? [duplicate]测试一个数字是否是素数的最快方法? [复制]
【发布时间】:2017-10-20 03:24:17
【问题描述】:

我正在尝试使用 Python 快速确定数字是否为素数。

我有两个功能可以做到这一点。两者都返回 True 或 False。

函数 isPrime1 很快返回 False 是一个数字不是一个素数。例如有一个大数字。但是对于大素数测试 True 很慢。

函数 isPrime2 对素数返回 True 更快。但是如果一个数字很大并且不是素数,那么返回一个值需要很长时间。第一个函数可以更好地使用它。

我怎样才能想出一个解决方案,它可以快速为非素数的大数返回 False,并且可以快速处理素数的大数?

def isPrime1(number): #Works well with big numbers that are not prime
    state = True
    if number <= 0:
        state = False
        return state
    else:          
        for i in range(2,number):
            if number % i == 0:
                state = False
                break
        return state

def isPrime2(number): #Works well with big numbers that are prime   
    d = 2
    while d*d <= number:
        while (number % d) == 0:            
            number //= d
        d += 1
    if number > 1:       
        return True
    else:
        return False`

【问题讨论】:

  • 使用预先初始化的 Bloom 过滤器,其中包含您需要考虑的最大素数列表。
  • 多大?请非常具体,因为答案将直接取决于此。
  • @RoryDaulton:不确定这是一个很好的副本。素性测试是一个比全面分解更容易的问题。
  • 仍然是错误的副本。素数分解和素数检验不是一回事。检查一个 1000 位数字是否(可能)是素数非常快;对这样的数字进行确定性素数检查会更慢,但仍然可行。但这超出了有效分解的范围。

标签: python math primes


【解决方案1】:

详尽的除法,直到平方根是您能想到的最简单的。最坏的情况是素数,因为必须执行所有除法。无论如何,直到十亿,几乎没有可测量的时间(1000000007 大约 1.2 毫秒)。

def Prime(n):
    if n & 1 == 0:
        return 2
    d= 3
    while d * d <= n:
        if n % d == 0:
            return d
        d= d + 2
    return 0

请注意,此版本返回最小除数或0,而不是布尔值。

一些微优化是可能的(例如使用增量表),但我认为它们不会产生很大的收益。

有更复杂和更快的方法可用,但我不确定它们是否值得为这么小的n 大惊小怪。

【讨论】:

    【解决方案2】:

    素性测试是一个非常棘手的话题。

    在尝试加速您的代码之前,请尝试确保它按预期工作。 我建议你从非常简单的算法开始,然后从那里构建。

    有趣的是,isPrime2 存在缺陷。它为 6、10、12、...返回 True

    第 3 到 6 行很有说服力

    while d*d <= number:
        while (number % d) == 0:            
            number //= d
        d += 1
    

    当找到number d 的因子时,数字会更新为number = number // d,并且在while 循环结束时,如果数字> 1,则返回True

    使用number = 6 处理代码:

    isPrime2(6)
    initialise> number := 6
    initialise> d := 2
    line3> check (2 * 2 < 6)     :True
    line4> check (6 % 2 == 0)    :True
    line5> update (number := 6//2) -> number = 3
    line6> update (d : d + 1) -> d = 3
    jump to line3
    line3> check (3 * 3 < 3)      :False -> GOTO line7
    line7> check(number > 1) -> check(3 > 1) :True
    line8> return True -> 6 is prime
    

    【讨论】:

    • isPrime1 是我写的一个函数,而 isPrime2 是我修改的,它实际上是为了计算一个数的素因数。第一个功能正在工作,让我处理第二个功能并修复它。谢谢
    【解决方案3】:

    这是我想出来的

    def is_prime(number):
        # if number is equal to or less than 1, return False
        if number <= 1:
            return False
    
        for x in range(2, number):
            # if number is divisble by x, return False
            if not number % x:
                return False
        return True
    

    【讨论】:

    • 豪法。您的函数的第一行与注释不匹配。 ``not number % 2`` 部分将对所有奇数返回 False,这意味着它将对除 2 之外的每个素数返回 False。请相应地修改函数。
    • 你的函数比我的第一个更快。 isPrime1(1000000007) 在 70 秒内给出结果,is_Prime(1000000007) 在 60 秒内给出结果。它更好,但让我们看看其他人有什么会更快。
    • @XeroSmith 我已经进行了更改。感谢指正
    • 测试到number 完全是浪费。你可以停在√number。对于1000000007,这大约是30000 的两倍。
    • 为什么只需要上平方根
    猜你喜欢
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    • 2016-08-02
    • 2020-11-21
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    相关资源
    最近更新 更多