0

因此,我编写了一个小程序来查找 5、4、3、2、1 的最小公倍数:

num = 1
multiples_list = []

for divisor in range(1,6):
    multiples_list.append(divisor)

multiple_5 = 5 * num
index = len(multiples_list) - 2

while index > 0:
    if multiple_5 % multiples_list[index] == 0:
        index -= 1
    else:
        num += 1
        index = len(multiples_list) - 2

if index == 0:
    print(multiple_5)

似乎我已经创建了一个无限循环......但是为什么呢?

4

4 回答 4

2

我想通了...这条线

multiple_5 = 5 * num

应该在 while 循环内,而不是在它之外。因为它在 while 循环之外,所以当 num 递增时它永远不会更新。

于 2013-09-29T08:16:30.443 回答
1

我认为你的算法是:考虑最大数的倍数(这里是 5)。当这个倍数是所有数字的倍数时停止。

以下是您可以如何编码的方法。

def lcm(*args):
    maxv = max(args)
    n = maxv
    while any(n % x for x in args):
        n += maxv
    return n

print lcm(1, 2, 3, 4, 5)

调试代码的一种非常有用的方法是在开始编码之前编写测试。这使您可以确保您的代码在各种情况下都能正常工作,并且当您发现并修复一个问题时,您不会重新引入已经修复的错误。我感觉您一直在针对单个示例(1、2、3、4、5)调试您的代码,因此您有点过于关注其中的细节。

这是我为检查上述代码而编写的实际测试代码:

cases = [
    ((1, 2), 2),
    ((2, 3), 6),
    ((2, 4), 4),
    ((2, 3, 4), 12)
]
for xs, want in cases:
    if want != lcm(*xs): print('lcm(%s) = %s, want %s' % (xs, lcm(*xs), want))

注意,你不需要任何花哨的东西,只需要一堆你知道答案的例子,然后运行它们,看看你的代码是否产生了你期望的相同答案。如果有任何差异,这里只是打印到控制台。随着您变得越来越复杂,您可以使用 unittest 模块,并将测试分开,但是当您学习快速代码时,它是矫枉过正的。

于 2013-09-29T09:12:37.410 回答
1

好的,让我们单步执行循环,一次一个循环,看看发生了什么。

循环1:

index 为 3,因此 multiples_list[index] 将为 4

multiple_5 是 5,所以 multiple_5 % multiples_list[index] 将是 1

1不等于0,所以num会加1,index设置为3

循环2:

index 为 3,因此 multiples_list[index] 将为 4

multiple_5 是 5,所以 multiple_5 % multiples_list[index] 将是 1

1 不等于 0,因此 num 将增加 1 并且 index 设置为 3

循环 3:

index 为 3,因此 multiples_list[index] 将为 4

multiple_5 是 5,所以 multiple_5 % multiples_list[index] 将是 1

1 不等于 0,因此 num 将增加 1 并且 index 设置为 3

所以你看,没有一个循环做任何不同的事情,只是稳步增加 num 的值,你没有在循环中测试,所以循环继续广告。无限。

于 2013-09-29T08:15:37.253 回答
0

我认为您忘记了索引从零开始,而不是从一开始。

while index > 0. 一开始,index将是3,因为那是5 - 2

multiple_5 % multiples_list[index] == 0:将是 False,因为5 % 4 == 1. 索引从零开始,所以multiples_list[3]也是4

所以 thennum加一,index变成len(multiples_list) - 2,也就是3,再一次。

于 2013-09-29T08:02:21.117 回答