有一个例如510510
主要除数是:[2, 3, 5, 7, 11, 13, 17]
使用素数列表,计算非素数除数的有效方法是什么?
答案 0 :(得分:3)
假设素数因子列表包含根据多重性的所有因子,您可以使用
prime_factors = [2, 3, 5, 7, 11, 13, 17]
non_prime_factors = [reduce(operator.mul, f)
for k in range(2, len(prime_factors) + 1)
for f in itertools.combinations(prime_factors, k)]
获得所有非素因素。请注意,如果某些素数因子的多重性大于1,则可能会出现重复 - 这些可以使用set(non_prime_factors)
过滤掉。
(在这种情况下,NumPy不会帮助太多。)
编辑:通过“包含根据多重性的所有因素”,我的意思是(例如)2应该在列表中出现两次,如果它是多重性2的素数因子,即4是2的最高幂,即数量因素。
编辑2:如果存在具有高多重性的素因子,则上述代码效率低下。所以,如果你需要这个,这里也是有效的代码。
primes = [2, 3, 5]
multiplicities = [3, 4, 5]
exponents = itertools.product(*(range(n + 1) for n in multiplicities))
factors = (itertools.izip(primes, e) for e in exponents if sum(e) >= 2)
non_prime_factors = [reduce(operator.mul, (p ** e for p, e in f))
for f in factors]
答案 1 :(得分:1)
这是让你开始的事情。在这个方法中,因子是一个素数映射到它们的数量。因此,对于您的情况,它看起来像[2 : 1, 3 : 1, 5 : 1, 7 : 1, 11 : 1, 13 : 1, 17 : 1]
。请注意,这会找到所有除数,但修改应该是微不足道的。
def findAllD(factors):
pCount = [0 for p in factors.keys()]
pVals = [p for p in factors.keys()]
iters = reduce(lambda x, y: x*y, [c+1 for c in factors.values()])
ret = []
for i in xrange(0, iters):
num = 1
for j in range(0, len(pCount)):
num *= pVals[j]**pCount[j]
ret.append(num)
for j in range(0, len(pCount)):
pCount[j] = pCount[j] + 1
if pCount[j] > factors[pVals[j]]:
pCount[j] = 0
else:
break;
return ret
答案 2 :(得分:1)
由于数字 510510 等于 2 * 3 * 5 * 7 * 11 * 13 * 17 ,所以每对素数乘以也是非素数除数:< / p>
>>> divmod(510510, 2*3)
(85085, 0)
>>> divmod(510510, 11*17)
(2730, 0)
6(= 2 * 3)和187(= 11 * 17)是非素数,并且是510510的正分除数。
您可以使用itertools轻松找到所有数字对:
>>> a=[2, 3, 5, 7, 11, 13, 17]
>>> list(itertools.combinations(a, 2))
[(2, 3), (2, 5), (2, 7), (2, 11), (2, 13), (2, 17), (3, 5), (3, 7), (3, 11), (3,
13), (3, 17), (5, 7), (5, 11), (5, 13), (5, 17), (7, 11), (7, 13), (7, 17), (11
, 13), (11, 17), (13, 17)]
然后,您需要做的就是将第一个数字乘以第二个数字:
>>> a
[2, 3, 5, 7, 11, 13, 17]
>>> b=list(itertools.combinations(a, 2))
>>> [d*e for d,e in b]
[6, 10, 14, 22, 26, 34, 15, 21, 33, 39, 51, 35, 55, 65, 85, 77, 91, 119, 143, 187, 221]
最后,你需要重复相同的程序三倍,四个等等,将适当的数字作为第二个参数传递给组合():
>>> b=[reduce((lambda o, p: o*p), y, 1) for x in xrange(2, len(a)) for y in itertools.combinations(a, x)]
>>> b
[6, 10, 14, 22, 26, 34, 15, 21, 33, 39, 51, 35, 55, 65, 85, 77, 91, 119, 143, 187, 221, 30, 42, 66, 78, 102, 70, 110, 130, 170, 154, 182, 238, 286, 374, 442, 105, 165, 195, 255, 231, 273, 357, 429, 561, 663, 385, 455, 595, 715, 935, 1105, 1001, 1309, 1547, 2431, 210, 330, 390, 510, 462, 546, 714, 858, 1122, 1326, 770, 910, 1190, 1430, 1870, 2210, 2002, 2618, 3094, 4862, 1155, 1365, 1785, 2145, 2805, 3315, 3003, 3927, 4641, 7293, 5005, 6545, 7735, 12155, 17017, 2310, 2730, 3570, 4290, 5610, 6630, 6006, 7854, 9282, 14586, 10010, 13090, 15470, 24310, 34034, 15015, 19635, 23205, 36465, 51051, 85085, 30030, 39270, 46410, 72930, 102102, 170170, 255255]
答案 3 :(得分:0)
如果对于某些d = |D|
,D是N和N = \prod_i=1^d(D[i]^p[i])
的素数除数的集合而不是p[i]
(其中p [i]是自然数> 0)。
从这个角度来看,您可以使用位掩码来遍历D
中所有可能的元素组合,并生成部分乘积,这将划分N
。当然,每个元素都要经历所有权力1...p[i]
。
在这种情况下,你将获得N的所有可能的非素数除数。
答案 4 :(得分:0)
如果您的意思是想要生成510510的所有除数:
每个素数除数在产品中只出现一次。
可以使用或不使用每个素数除数。因此,将其视为从0到127的二进制集,并查看位。迭代数字,如果设置了与素数除数有关的位,则包含该素数。
例如二进制1011010表示使用数字17,11,7和3,因此乘以这些得到3927
当然0000000涉及1和1111111到510510,所以你可能不想计算“1和它自己”。
如果你有一个具有多个因子的数字,你必须在该因子上计算0到n,例如60是2 * 2 * 3 * 5所以0-2使用2,0-1使用3,0- 1使用5,总共12个可能的因素(包括1和60)。