【问题标题】:Prime factorisation program in python gives no outputpython中的素数分解程序没有输出
【发布时间】:2017-02-04 14:50:23
【问题描述】:

我正在研究欧拉问题 3 的项目,

13195的质因数是5、7、13和29。600851475143的最大质因数是多少?

我想出的代码如下:

def q_prime(a):
    if a == 2:
            return True
    elif a < 2:
            return False

    for i in range(2,a):


            if a%i == 0:
                    return False
    else:
            return True


def prime_factor(x):
    prime_factors =[]
    for i in range(1,x):
            if q_prime(i) == True and x%i == 0:
                    prime_factors.append(i)
    return prime_factors

调用 13195 的这个函数给了我 [5,7,13,29] 的预期。我尝试了一些其他的组合,比如 1035,它给出了 [3,5,23]。但是,当我在 600851475143 上调用此函数时,我没有得到任何输出。此外,我也没有收到错误消息。运行一会,简单重启shell

我知道这不是一个优雅的代码,而且我猜想对大量此类问题进行暴力破解会导致此问题?到底发生了什么?

【问题讨论】:

    标签: python prime-factoring


    【解决方案1】:

    数字 600851475143 太大。如果在q_primeprime_factor 中检查数字不在[2, n] 范围内的数字,则可以简化计算。这也将返回正确的结果,但花费的时间更少:

    import math
    
    def q_prime(a):
        if a == 2:
                return True
        elif a < 2:
                return False
    
        for i in range(2, int(math.sqrt(a) + 1)):
                if a%i == 0:
                    return False
        else:
            return True
    
    
    def prime_factor(x):
        prime_factors =[]
        for i in range(1, int(math.sqrt(x) + 1)):
                if q_prime(i) == True and x%i == 0:
                        prime_factors.append(i)
        return prime_factors
    

    【讨论】:

    • 选择 sqrt(n) 的原因是什么?
    • @getafix 如果一个数的除数小于 sqrt(n) 然后另一个大于。并且更大的除数也将小于 sqrt(n)。所以检查大于 sqrt(n) 的数字是过度的。
    【解决方案2】:

    考虑到问题的规模,您编写的两个函数都有问题。 q_prime(a) 循环到 aprime_factor(x) 循环到 x 调用 q_prime 每次迭代。这使得你的算法 O(N^2) 对于像 600851475143 这样的数字来说太过分了。

    更好的方法(O(√N) -> 基本上立即的结果):

    • 使用sieve of Eratosthenes 生成素数的生成器函数
    • 遍历素数直到sqrt(n)收集因子,同时缩小n找到每个因子
      • 如果没有发现其他因素,请自行添加n

    【讨论】:

    • 嗨!感谢您的回复,我尝试实施您的建议(或至少我对它的解释),您介意看一下吗? pastebin.com/PxTgsei6 它仍然不适用于大数字。这个算法是否仍然可以扩展为 $\mathcal{O}(N^2)$ 我应该使用集合来加快速度吗?
    【解决方案3】:

    当我尝试使用 Python 2.7 运行您的代码时会发生以下情况:

    $ python primes.py
    Killed: 9
    

    问题在于range(2, 600851475143) 试图创建一个包含 600851475141 个元素的列表。这太大了,无法放入计算机的内存中,因此 Python 程序会被终止。

    您可以尝试将range() 替换为xrange(),但您的程序需要很长时间才能完成。你需要一个更好的算法。

    附:您的代码中还有一个错误,这意味着它不适用于主要输入。

    【讨论】:

    • 我明白了。所以我猜需要一个更好的算法?回到绘图板。 “杀死:9”是什么意思?
    • @getafix: 9 是 SIGKILL 的信号编号。细节在这里不是很重要,但这里有一些信息:en.wikipedia.org/wiki/Unix_signal#SIGKILL
    猜你喜欢
    • 2016-12-06
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 2022-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多