小怪兽爱吃肉
您可以改变策略并从共同素因数的角度来解决这个问题。n 和 m 之间的公共互质将是不能被任何公共质因数整除的所有数字。def primeFactors(N): p = 2 while p*p<=N: count = 0 while N%p == 0: count += 1 N //= p if count: yield p p += 1 + (p&1) if N>1: yield Nimport mathdef compare2(n,m): # skip list for multiples of common prime factors skip = { p:p for p in primeFactors(math.gcd(n,m)) } for x in range(1,min(m,n)): if x in skip: p = skip[x] # skip multiple of common prime m = x + p # determine next multiple to skip while m in skip: m += p # for that prime skip[m] = p else: yield x # comon coprime of n and m 性能比匹配互质列表要好得多,尤其是在较大的数字上:from timeit import timeittimeit(lambda:list(compare2(10**5,2*10**5)),number=1)# 0.025 secondtimeit(lambda:list(compare2(10**6,2*10**6)),number=1)# 0.196 secondtimeit(lambda:list(compare2(10**7,2*10**7)),number=1)# 2.18 secondstimeit(lambda:list(compare2(10**8,2*10**8)),number=1)# 20.3 secondstimeit(lambda:list(compare2(10**9,2*10**9)),number=1)# 504 seconds在某些时候,构建所有互质列表会成为瓶颈,您应该在它们从生成器中出来时使用/处理它们(例如计算有多少个):timeit(lambda:sum(1 for _ in compare2(10**9,2*10**9)),number=1)# 341 seconds解决这个问题的另一种方法是列出 n 和 m 之间的 gcd 的互质数,该方法比质因数方法慢一些,但编码更简单:import mathdef compare3(n,m): d = math.gcd(n,m) for c in range(1,min(n,m)): if math.gcd(c,d) == 1: yield ctimeit(lambda:list(compare3(10**6,2*10**6)),number=1)# 0.28 secondtimeit(lambda:list(compare3(10**7,2*10**7)),number=1)# 2.84 secondstimeit(lambda:list(compare3(10**8,2*10**8)),number=1)# 30.8 seconds鉴于它不使用内存资源,因此在某些情况下可能是有利的:timeit(lambda:sum(1 for _ in compare3(10**9,2*10**9)),number=1)# 326 seconds