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}