Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 素因子分解:不';你不能和大数字打交道吗?_Python - Fatal编程技术网

Python 素因子分解:不';你不能和大数字打交道吗?

Python 素因子分解:不';你不能和大数字打交道吗?,python,Python,我想找出一个数的最大素因子。当与较小的数字一起使用时,代码在空闲状态下正确运行,但当我将较大的数字(如600851475143)分配给n时,代码似乎根本不会在屏幕上打印任何内容。为什么? def isPrime(n): isPrime = True for i in range(2,n-1): if n % i == 0: isPrime = False return isPrime largest = 0 n = 60

我想找出一个数的最大素因子。当与较小的数字一起使用时,代码在空闲状态下正确运行,但当我将较大的数字(如600851475143)分配给n时,代码似乎根本不会在屏幕上打印任何内容。为什么?

def isPrime(n):
    isPrime = True
    for i in range(2,n-1):
        if n % i == 0:
            isPrime =  False
        return isPrime

largest = 0
n = 600851475143
for i in range(2,n-1):
    if isPrime(i) and n % i == 0:
        largest = i
        n = n / i
        continue

print("The largest prime factor is", largest)
顺便说一下,我正在运行Python 3.3

==============================================================================

谢谢大家

我修改了我的原始代码如下:

def isPrime(n):
    for i in range(2,n-1):
        if n % i == 0:
            return False
    return True

largest = 0
n = 600851475143
for i in range(2,n-1):
    if isPrime(i) and n % i == 0:
        largest = i
        if i == n:
            break
        n = n / i

print("The largest prime factor is", largest)
正如Nakedfanic所说,他们的代码运行得更快,我对其进行了轻微的编辑:

largest = 0
n = 600851475143
i = 2
while True:
    if n % i == 0:
        largest = i
        if n == i:
            # finished
            break
        n = n / i
    else:
        i += 1

print("The largest prime factor is", largest)

最有可能的是,您的代码没有以大的
n
终止,这仅仅是因为循环运行的时间太长。

最有可能的是,您的代码没有以大的
n
终止,这仅仅是因为循环运行的时间太长

isPrime = True
for i in range(2,n-1):
    if n % i == 0:
        isPrime =  False
    return isPrime
由于无条件的
返回
,此循环始终退出第一次迭代。尝试:

for i in range(2,n-1):
    if n % i == 0:
        return False

return True
此外,上限
n-1
可以减少为
sqrt(n)+1

由于无条件的
返回
,此循环始终退出第一次迭代。尝试:

for i in range(2,n-1):
    if n % i == 0:
        return False

return True

此外,上限
n-1
可以减少到
sqrt(n)+1

有几个优化方面:

  • 所有因子分解只需达到
    sqrt(n)
    (含)

  • isPrime()
    转换为表查找

    使用
    n
    初始化查找表,然后只计算一次所有素数
    ,并循环遍历它们。
    正如评论所指出的,这会占用大量内存空间。我们可以使用bit flag将内存需求减少到1/8,如果我们跳过所有偶数,我们可以将内存需求再减少一半(然后必须分别测试n是否为偶数)。但对于大型
    n
    ,这可能仍然令人望而生畏

  • (如果使用当前代码)在
    isPrime()
    中提前返回(由@justhalf编写)

  • 查找最大因子时向后循环(从
    sqrt(n)
    到2)

  • 如果商除以因子(除以@justhalf)后为1,则提前返回


  • 这篇文章(由@prashant建议)包含了更复杂的算法(使我的建议非常幼稚)>有几个优化方面:

    • 所有因子分解只需达到
      sqrt(n)
      (含)

    • isPrime()
      转换为表查找

      使用
      n
      初始化查找表,然后只计算一次所有素数
      ,并循环遍历它们。
      正如评论所指出的,这会占用大量内存空间。我们可以使用bit flag将内存需求减少到1/8,如果我们跳过所有偶数,我们可以将其再减少一半(然后必须分别测试n是否为偶数)。但对于大的
      n
      ,这可能仍然令人望而生畏

    • (如果使用当前代码)在
      isPrime()
      中提前返回(由@justhalf编写)

    • 查找最大因子时向后循环(从
      sqrt(n)
      到2)

    • 如果商除以因子(除以@justhalf)后为1,则提前返回


    • 这篇文章(由@prashant建议)包含了更复杂的算法(使我的建议非常幼稚)这是因为即使
      n
      已经是1,你仍在不断尝试

      此代码将帮助您查看问题:

      def isPrime(n):
          for i in xrange(2,n-1):
              if n % i == 0:
                  return False
          return True
      
      largest = 0
      n = 600851475143
      for i in xrange(2,n-1):
          print 'Checking whether %d divides %d' % (i,n)
          if isPrime(i) and n % i == 0:
              largest = i
              n = n / i
              continue
      
      print("The largest prime factor is", largest)
      
      这将产生:

      ... Checking whether 6857 divides 6857 Checking whether 6858 divides 1 Checking whether 6859 divides 1 Checking whether 6860 divides 1 Checking whether 6861 divides 1 Checking whether 6862 divides 1 Checking whether 6863 divides 1 Checking whether 6864 divides 1 Checking whether 6865 divides 1 Checking whether 6866 divides 1 Checking whether 6867 divides 1 Checking whether 6868 divides 1 Checking whether 6869 divides 1 Checking whether 6870 divides 1 Checking whether 6871 divides 1 Checking whether 6872 divides 1 Checking whether 6873 divides 1 ...
      无论如何,你的代码可能会有很大的改进,哈哈,看看其他人的建议。

      这是因为你一直在尝试,即使
      n
      已经是1

      此代码将帮助您查看问题:

      def isPrime(n):
          for i in xrange(2,n-1):
              if n % i == 0:
                  return False
          return True
      
      largest = 0
      n = 600851475143
      for i in xrange(2,n-1):
          print 'Checking whether %d divides %d' % (i,n)
          if isPrime(i) and n % i == 0:
              largest = i
              n = n / i
              continue
      
      print("The largest prime factor is", largest)
      
      这将产生:

      ... Checking whether 6857 divides 6857 Checking whether 6858 divides 1 Checking whether 6859 divides 1 Checking whether 6860 divides 1 Checking whether 6861 divides 1 Checking whether 6862 divides 1 Checking whether 6863 divides 1 Checking whether 6864 divides 1 Checking whether 6865 divides 1 Checking whether 6866 divides 1 Checking whether 6867 divides 1 Checking whether 6868 divides 1 Checking whether 6869 divides 1 Checking whether 6870 divides 1 Checking whether 6871 divides 1 Checking whether 6872 divides 1 Checking whether 6873 divides 1 ... 无论如何,您的代码可能会有很大的改进,哈哈,请参考其他人的建议。

      您的代码运行时间为O(n²),这意味着随着n的增加,它将很快变得异常缓慢。这就是为什么您的算法适用于小值,但适用于大值

      这段代码在O(n)时间内做同样的事情,根本不做任何素数检查,并立即返回一个结果:

      prime_factors = []
      n = 600851475143
      i = 2
      while True:
          if n % i == 0:
              prime_factors.append(i)
              if n == i:
                  # finished
                  break
              n = n / i
          else:
              i += 1
      
      print("The largest prime factor is", prime_factors[-1])
      
      您的代码运行时间为O(n²),这意味着随着n的大小的增加,它将很快变得异常缓慢。这就是为什么您的算法适用于小值,但适用于大值

      这段代码在O(n)时间内做同样的事情,根本不做任何素数检查,并立即返回一个结果:

      prime_factors = []
      n = 600851475143
      i = 2
      while True:
          if n % i == 0:
              prime_factors.append(i)
              if n == i:
                  # finished
                  break
              n = n / i
          else:
              i += 1
      
      print("The largest prime factor is", prime_factors[-1])
      

      更困难的问题可能需要不同的算法

      查看此问题:

      您的代码看起来不错,但可能需要很长时间才能完成一个大的
      n
      。利用数学可以使您更快地解决这个问题

      在这个链接上,我建议纯python解决方案使用
      rwh_primes1
      ,而使用numpy的解决方案则使用
      primesfrom3to
      。这两种实现都相当简短,相对清晰,基本上做的是相同的事情。这些代码片段是用python 2编写的,因此翻译可能如下:

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

      更困难的问题可能需要不同的算法

      查看此问题:

      您的代码看起来不错,但可能需要很长时间才能完成一个大的
      n
      。利用数学可以使您更快地解决这个问题

      在这个链接上,我建议纯python解决方案使用
      rwh_primes1
      ,而使用numpy的解决方案则使用
      primesfrom3to
      。这两种实现都相当简短,相对清晰,基本上做的是相同的事情。这些代码片段是用python 2编写的,因此翻译可能如下:

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

      代码的另一个可能会减慢速度的方面是代码的后半部分

      largest = 0
      n = 600851475143
      for i in range(2,n-1):
          if isPrime(i) and n % i == 0:
              largest = i
              n = n / i
              continue
      
      特别是声明

      if isPrime(i) and n % i == 0: 
      
      根据,仅当第一个条件为
      True
      时,才会计算第二个条件。在您的情况下,更合理的做法是反转条件,以便始终执行计算上昂贵的除法,并且更昂贵的
      isPrime()
      仅为cal