Python中的因子分解

在一个项目欧拉问题中,需要对一个数字进行因式分解。我们已经有了这个数字的所有质因数。根据算术基本定理,我们可以用这个列表推导出这个数字的所有因子。
在这里插入图片描述

我们目前的计划是取基本质因数列表中的每个数字,并将其幂提高直到它不再是整数因子,以找到每个质因数的最大指数。然后,我们将各个质数指数对的所有可能组合相乘。例如,对于180:

给定:180的质因数:[2, 3, 5]
找到每个因子的最大指数:
180 / 2^1 = 90
180 / 2^2 = 45
180 / 2^3 = 22.5 - 不是整数,所以2是2的最大指数。

180 / 3^1 = 60
180 / 3^2 = 20
180 / 3^3 = 6.6 - 不是整数,所以2是3的最大指数。

180 / 5^1 = 36
180 / 5^2 = 7.2 - 不是整数,所以1是5的最大指数。

然后,我们对这些指数组合进行各种组合,直到最大指数,以获得因子:
2^0 * 3^0 * 5^0 = 1
2^1 * 3^0 * 5^0 = 2
2^2 * 3^0 * 5^0 = 4
2^0 * 3^1 * 5^0 = 3
2^1 * 3^1 * 5^0 = 6
2^2 * 3^1 * 5^0 = 12
2^0 * 3^2 * 5^0 = 9
2^1 * 3^2 * 5^0 = 18
2^2 * 3^2 * 5^0 = 36
2^0 * 3^0 * 5^1 = 5
2^1 * 3^0 * 5^1 = 10
2^2 * 3^0 * 5^1 = 20
2^0 * 3^1 * 5^1 = 15
2^1 * 3^1 * 5^1 = 30
2^2 * 3^1 * 5^1 = 60
2^0 * 3^2 * 5^1 = 45
2^1 * 3^2 * 5^1 = 90
2^2 * 3^2 * 5^1 = 180

因此,因子的列表 = [1, 2, 3, 4, 5, 6, 9, 10, 12, 15, 18, 20, 30, 36, 45, 60, 90, 180]

这是我们目前为止的代码。有两个问题:第一,我们认为它一点也不Pythonic。我们想修复它。第二,我们真的没有Pythonic的方法来做组合的第二步。为了避免尴尬,我们没有给你展示那套可笑的循环。

n 是我们要分解的数字。listOfAllPrimes是预先计算的列表,其中包含多达 1000 万的质数。

def getListOfFactors(n, listOfAllPrimes):
    maxFactor = int(math.sqrt(n)) + 1
    eligiblePrimes = filter(lambda x: x <= maxFactor, listOfAllPrimes)
    listOfBasePrimes = filter(lambda x: n % x ==0, eligiblePrimes)

    listOfExponents = [] #(do I have to do this?)
    for x in listOfBasePrimes:
        y = 1
        while (x**(y+1)) % n == 0:
            y += 1
        listOfExponents.append(y)

2、解决方案

方案一

建议使用 itertools.combinations 来获取所有可能的因子组合。之后,只需将每个组合中的项相乘即可得到因子。

import itertools

def get_factors(n):
  prime_factors = get_prime_factors(n)  # get the prime factors of n
  factor_combinations = itertools.product(*prime_factors)  # get all possible combinations of factors
  factors = [reduce(lambda x, y: x * y, combination) for combination in factor_combinations]  # multiply the factors in each combination
  return factors

def get_prime_factors(n):
  prime_factors = []
  divisor = 2
  while n > 1:
    if n % divisor == 0:
      prime_factors.append(divisor)
      n //= divisor
    else:
      divisor += 1
  return prime_factors

方案二

建议使用filter()和map()函数来生成质因数列表,然后使用product()函数来生成所有可能的因子组合。

from itertools import product

def get_factors(n):
  prime_factors = list(filter(lambda x: n % x == 0, range(2, int(n**0.5) + 1)))
  if prime_factors[-1]**2 == n:
    prime_factors.pop()
  factors = [reduce(lambda x, y: x * y, combination) for combination in product(prime_factors, repeat=2)]
  return set(factors)  # remove duplicates
  • 24
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值