我正在编写一个代码,用于计算下面函数g(x)
中与自然数相关的差距,然后将它们相加。
from math import *
a = set()
n = eval(input("n = "))
def g(x):
return floor(x*log10(x)) # thanks to tzaman
b = 1
while g(b) < n:
a.add(g(b))
b+=1
aprime = set(range(max(a)))
z = max(a)
print(z*(z+1)/2-sum(a)) # thanks to tzaman
input("Done!")
我正在尝试n = 10 ** 10
,即10000000000
,并在合理的时间内执行计算(例如,<10分钟)。但是,这段代码执行起来很荒谬,我想知道:有没有更有效的方法呢?
n = 12, output = 15
以下图表将x
与g(x)
进行了比较:
x | 1 2 3 4 5 6 7 8 9 10 11 12
g(x) | 0 0 1 2 3 4 5 7 8 10 11 12
集合x \ g(x)
代表x
中不在g(x)
的成员,对于低于12的数字{0,6,9}
;这些的总和是15.所以,当n = 12
,output = 15
。
答案 0 :(得分:1)
您的麻烦可能来自sum(aprime-a)
行。这会强制python计算两组的集合差异。考虑到您的设置有多大,这会浪费很多时间。
当sum(a-b) = sum(a)-sum(b)
是b
的子集时(而不是你的情况),请注意a
。所以我们现在有sum(aprime)-sum(a)
。
接下来利用aprime
只是算术序列的事实!你有一个公式来计算这些东西的总和!而不是sum(aprime)
你可以做
maxVal = max(a)
sumAPrime = ((maxVal +1)*maxVal)/2
所以你现在有sumAPrime - sum(a)
作为你的解决方案!
我将假设您需要优化以适用于任意函数g
,因此您无法对代码中的函数进行假设。
希望这有帮助! :)
答案 1 :(得分:1)
我不确定它会有多大影响,但您可以阻止使用set()
和eval()
。 eval()
可以更改为int()
,因为您已将n =设置为输入结果。接下来,您可以在迭代中检查g中的g(b)的值。删除aprime并将a更改为列表将提供以下内容。
from math import *
a = []
n = int(input("n = "))
def g(x):
return floor(x*log10(x))
b = 1
while g(b) < n:
if g(b) in a:
b+=1
else:
a.append(g(b))
b+=1
z = max(a)
print(z*(z+1)/2-sum(a))
input("Done!")