【发布时间】:2015-05-05 22:39:55
【问题描述】:
我不知道如何加快对给定范围内的倍数求和的算法。这是针对 codewars.com 上的问题 这里是问题的链接 codewars link
这是代码,我将在底部解释发生了什么
import itertools
def solution(number):
return multiples(3, number) + multiples(5, number) - multiples(15, number)
def multiples(m, count):
l = 0
for i in itertools.count(m, m):
if i < count:
l += i
else:
break
return l
print solution(50000000) #takes 41.8 seconds
#one of the testers takes 50000000000000000000000000000000000000000 as input
# def multiples(m, count):
# l = 0
# for i in xrange(m,count ,m):
# l += i
# return l
所以基本上问题要求用户返回一个数字中所有 3 和 5 的倍数的总和。这是测试人员。
test.assert_equals(solution(10), 23)
test.assert_equals(solution(20), 78)
test.assert_equals(solution(100), 2318)
test.assert_equals(solution(200), 9168)
test.assert_equals(solution(1000), 233168)
test.assert_equals(solution(10000), 23331668)
我的程序得到正确答案没有问题。当输入很大时就会出现问题。当传入一个像 50000000 这样的数字时,需要 40 多秒才能返回答案。我被要求接受的输入之一是 500000000000000000000000000000000000000000,这是一个巨大的数字。这也是我使用itertools.count() 的原因我在第一次尝试中尝试使用xrange 但范围无法处理大于c 类型long 的数字。我知道问题最慢的部分是倍数方法......但它仍然比我第一次尝试使用列表理解并检查i % 3 == 0 or i % 5 == 0,有什么想法吗?
【问题讨论】:
-
真正的优化将是一种不同的方法。你不需要遍历范围内的所有数字,这个问题有一个封闭形式的解决方案
-
我在 google 上搜索了封闭形式,得到的定义是,“如果一个方程根据给定的函数和数学运算来解决给定的问题,那么它就是一个封闭形式的解——可接受的集合。例如,无限和通常不会被视为封闭形式。读完之后,我仍然对封闭形式的含义感到困惑。可以请教一下吗?
-
通过接近形式我的意思是你可以想出一个简单的算术函数,给定一个数字 n 和一个范围 r 会给你在范围 [0. .r]
-
我知道如何计算给定范围或数字内的倍数,我以前试过。我可以通过使用 ⌊b/n⌋ - ⌈a/n⌉ + 1 来计算一个数字中 3 和 5 的倍数,我在这里读到了 had2know.com/academics/…,我不知道如何应用它虽然因为问题是要求给定范围内所有倍数的总和,例如3、6、9 = 18,而 9 中有 3 个 3 的倍数。
-
你会很高兴听到还有一个用于计算等差数列之和的封闭式公式 :) en.wikipedia.org/wiki/Arithmetic_progression#Sum