天天看点

python3 高效实现 最大质因数/质因数集合 方法

def gcd(a, b):
    """
    greatest common divisor  # https://baike.baidu.com/item/欧几里得算法
    :param a: int
    :param b: int
    :return:
    """
    while b > 0:
        d = a % b
        a = b
        b = d
    return a


def ggf(n):
    """
    general Qualitative factors 生成质因数集合,第i个元素为i的质因数set,并剔除了1(为了节省内存)
    :param n:
    :return:
    """
    ret_li = [{0}, set(), {2}]
    for i in range(3, n+1):
        ret_li.append(set())  # append的既是ret_li[i]
        for j in range(2, int(i**.5) + 1):
            d, m = divmod(i, j)
            if m == 0:
                ret_li[i] = ret_li[d] | {j}
                break
        if len(ret_li[i]) == 0:
            ret_li[i] = {i}
    return ret_li


def gf_ic(n, c_di=None):
    """
    Qualitative factors use iter with cache dict ,直接修改传入的c_di, 没有结合ggf来获得c_di
    想加速还可以注释掉所有 if c_di is None的情况, 且保证一定传入c_di
    :param n:
    :param c_di:
    :return: c_di[n]
    """
    # if c_di is None:
    #     gfs_20 = ggf(20)
    #     c_di = {i: gfs_20[i] for i in range(1, 21)}
    if n not in c_di:
        for j in range(2, int(n ** .5) + 1):
            d, m = divmod(n, j)
            if m == 0:
                c_di[n] = gf_ic(d, c_di) | {j}
                break
    if n not in c_di:
        c_di[n] = {n}
    return c_di[n]           

通过如下代码进行测试:

gfs_20 = ggf(20)

c_di = {i: gfs_20[i] for i in range(1, 21)}

gf_ic(20, c_di)
Out[4]: {2, 5}
gf_ic(99, c_di)
Out[5]: {3, 11}
c_di
Out[6]: 
{1: set(),
 2: {2},
 3: {3},
 4: {2},
 5: {5},
 6: {2, 3},
 7: {7},
 8: {2},
 9: {3},
 10: {2, 5},
 11: {11},
 12: {2, 3},
 13: {13},
 14: {2, 7},
 15: {3, 5},
 16: {2},
 17: {17},
 18: {2, 3},
 19: {19},
 20: {2, 5},
 33: {3, 11},
 99: {3, 11}}
gf_ic(999999999, c_di)
Out[7]: {3, 37, 333667}