Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.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 求(N!)^2的除数_Python_Algorithm_Math - Fatal编程技术网

Python 求(N!)^2的除数

Python 求(N!)^2的除数,python,algorithm,math,Python,Algorithm,Math,我试图解决问题,我将其简化为: 求N的除数^二, 我编写了我的解决方案,我把它作为一个答案放在这里,因为我没有被指责没有做任何工作,它对大数字也能正常、快速地工作,但是由于超时,它没有通过所有测试,我认为我的算法效率不高 以下是我的想法概要: 任何数字都可以表示为a0^b1*a1^b1*..*an^bn,其中有1+b1*1+b2*..*1+bn除数 那么M^2将有1+2b1*1+2b2*..*1+2bn除数 创建一个函数,用于查找数字的所有因子并将它们保存为hashmap 有一个函数,通过添加相

我试图解决问题,我将其简化为: 求N的除数^二,

我编写了我的解决方案,我把它作为一个答案放在这里,因为我没有被指责没有做任何工作,它对大数字也能正常、快速地工作,但是由于超时,它没有通过所有测试,我认为我的算法效率不高

以下是我的想法概要:

任何数字都可以表示为a0^b1*a1^b1*..*an^bn,其中有1+b1*1+b2*..*1+bn除数 那么M^2将有1+2b1*1+2b2*..*1+2bn除数 创建一个函数,用于查找数字的所有因子并将它们保存为hashmap 有一个函数,通过添加相应键的值来组合两个哈希映射 使用这两个函数迭代从2到n的所有数字,以获得阶乘的所有除数 使用1中的函数。得到答案 我认为这个解决方案相当有效,但似乎有更好的方法。
有谁能给我推荐一个更好的方法吗?

你的问题有一个简单有效的解决方案。注意n!是:

让我们想想一个主要因素在这个产品中出现了多少次,例如2。 每2个因素出现一次。但每四个因素中就有一个会出现两次。每8个因素出现一次三次等。 换句话说,因子2将出现在n中!sumn//2**e代表范围1中的e,n次。对于任何素因子k也是如此

您可以通过以下方式实现此计算:

import itertools as it

def exp_for_factor_in_factorial(factor, n):
    total = 0
    for e in it.count(1):
        if factor ** e > n:
            break
        total += n // factor**e
    return total
现在,为了找到n的所有素因子!我们需要找到n以下的所有素数,这很容易用埃拉托斯烯实现:

import math

def sieve(n):
    nums = [True] * (n+1)
    nums[:2] = [False]*2
    nums[4::2] = [False] * math.ceil((n-3)/2)
    for i in range(3, int((n+1)**.5)+1, 2):
        if nums[i]:
            for j in range(i*i, n+1, 2*i):
                nums[j] = False
    return [i for i,k in enumerate(nums) if k]
这使得我们可以得到n的因式分解:

最后,要计算因式分解的除数,可以使用前面提到的公式:

import operator as op
from functools import reduce

def get_num_divisors(factorization):
    return reduce(op.mul, (e+1 for _, e in factorization), 1)
因此,最终的答案是:

def divs_of_squared_fact(n):
    return get_num_divisors((p, 2*e) for p, e in get_factorization_factorial(n))
请注意,此解决方案的性能远远高于您的:

In [41]: %%timeit
    ...: for i in range(2, 1000):
    ...:     x = divs_of_squared_fact(i)
    ...: 
1 loops, best of 3: 276 ms per loop

In [42]: %%timeit
    ...: for i in range(2, 1000):
    ...:     x = divisorsOfFactorialSquare(i)
    ...: 
1 loops, best of 3: 7.89 s per loop
它能够产生5000个除数^大约2毫秒内完成2次,而另一次几乎需要半秒:

In [47]: %timeit divs_of_squared_fact(5000)
100 loops, best of 3: 2.07 ms per loop

In [48]: %timeit divisorsOfFactorialSquare(5000)
1 loops, best of 3: 439 ms per loop

事实上,答案具有不同的渐近复杂性,因此当增加参数时,差异会无穷大。

对于此类问题,您可能会在@Vektor88上找到更好的答案。我考虑过这个问题,也考虑过代码审查,但我相信这是一个更好的地方。我不是反对者,但我真的认为,当涉及到性能或复杂性时,CS是一个更好的地方。但这只是一个建议。你肯定比我更了解和使用这个网站:谢谢你花时间写下这个详细的解释。解释和实现非常出色。
In [41]: %%timeit
    ...: for i in range(2, 1000):
    ...:     x = divs_of_squared_fact(i)
    ...: 
1 loops, best of 3: 276 ms per loop

In [42]: %%timeit
    ...: for i in range(2, 1000):
    ...:     x = divisorsOfFactorialSquare(i)
    ...: 
1 loops, best of 3: 7.89 s per loop
In [47]: %timeit divs_of_squared_fact(5000)
100 loops, best of 3: 2.07 ms per loop

In [48]: %timeit divisorsOfFactorialSquare(5000)
1 loops, best of 3: 439 ms per loop