Project Euler第12题Python代码输出异常求助
解决Project Euler第12题时的因数计数错误分析与修正
你遇到的问题核心在于全局列表facs没有在每次调用allfacof时重置,导致因数列表被持续累加,最终错误触发了循环的终止条件。
错误原因详解
你的facs是定义在函数外部的全局变量,每次调用allfacof(x)时,都会把当前数字的因数追加到这个列表里,而不是重新创建一个新列表。比如:
- 第一次计算第1个三角数
1,facs变成[1],长度为1; - 第二次计算第2个三角数
3,facs变成[1, 3],长度为2; - 第三次计算第3个三角数
6,facs变成[1, 3, 1, 2, 3, 6],长度为6; - 以此类推,后续每次调用都会把新的因数追加进去,列表长度是所有之前计算过的因数总数,而非当前三角数的实际因数数量。
当这个累计长度超过500时,循环就会错误终止,输出当时的三角数(也就是你看到的1378),但这个数字的实际因数数量只有8个。
修正方案
1. 修复因数计数函数
把facs移到allfacof函数内部,确保每次调用都重新初始化空列表:
def allfacof(x): facs = [] # 每次调用都创建新的空列表,避免累计 for i in range(1, int(x/2)+1): if x % i == 0: facs.append(i) facs.append(x) return facs
2. 优化三角数计算
原TriangularNo用循环累加效率很低,改用数学公式x*(x+1)//2可以直接计算第x个三角数:
def TriangularNo(x): return x * (x + 1) // 2
3. 高效计算因数数量(可选但推荐)
因为题目只需要因数的数量,不需要具体的因数列表,我们可以优化因数计数逻辑,只循环到sqrt(x),找到一个因数就同时统计对应的另一个因数,大幅提升效率(尤其是处理大数字时):
def count_factors(x): count = 0 sqrt_x = int(x**0.5) for i in range(1, sqrt_x + 1): if x % i == 0: # 如果i和x/i是同一个数(完全平方数),只加1;否则加2 count += 1 if i == x//i else 2 return count
修正后的完整代码
结合以上优化,最终的代码会更高效且正确:
def count_factors(x): count = 0 sqrt_x = int(x**0.5) for i in range(1, sqrt_x + 1): if x % i == 0: count += 1 if i == x//i else 2 return count def TriangularNo(x): return x * (x + 1) // 2 a = 0 while True: a += 1 triangular_num = TriangularNo(a) factor_count = count_factors(triangular_num) if factor_count >= 500: print(triangular_num) break
运行这段代码后,会正确输出首个因数超过500个的三角数:76576500。
内容的提问来源于stack exchange,提问作者Aaryan Dewan
相关产品推荐
相关产品推荐

