【问题标题】:Efficient algorithm for transforming a set with a function用函数转换集合的高效算法
【发布时间】:2015-08-12 19:09:51
【问题描述】:

我正在编写一个代码,它将计算下面函数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,并在合理的时间内(例如,


示例 I/O

n = 12, output = 15

其他信息

下图比较了xg(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 = 12output = 15

【问题讨论】:

  • 请解释问题所在,这样我们就不必推断您的代码试图做什么。
  • 如果len(a)len(aprime) 小得多,在这种情况下,您应该只计算sum(a) 并从sum(aprime) 的封闭形式中减去:@987654339 @
  • @JuanLopes I'm writing a code that will count the gaps in the function g(x) below... However, this code performs ludicrously long... 我相信我已经清楚地表达了我的问题;差距的定义不明确吗?
  • 这是一个编程问题的网站,所以如果您的代码与其他主题相关,我们可能无法立即理解。如果有不清楚的地方,最好给出示例输入和输出:)
  • 另外,我希望g(x) 只是这里的一个例子——如果这实际上是您正在使用的函数,那么将其转换为g(x) = floor(x*log10(x)) 对于大型x 会快很多.

标签: python algorithm function python-3.x


【解决方案1】:

您的麻烦可能来自sum(aprime-a) 这一行。这迫使 python 计算你的两组的集合差异。考虑到你的集合有多大,这是一个巨大的时间浪费。

ba 的子集时,请注意sum(a-b) = sum(a)-sum(b)(就像您的情况一样)。所以我们现在有了sum(aprime)-sum(a)

接下来利用aprime 只是一个等差数列这一事实!你有一个公式来计算这些东西的总和!你可以代替sum(aprime)

maxVal = max(a)
sumAPrime = ((maxVal +1)*maxVal)/2

所以你现在有sumAPrime - sum(a) 作为你的解决方案!

我将假设您需要优化以适用于任意函数 g,因此您不能对代码中的函数做出假设。

希望这会有所帮助! :)

【讨论】:

  • 不,实际上。 g 如上所述是我希望优化的功能,并不是任意的。至于您的优化,我确信它们是否会更好地用于大型 n
【解决方案2】:

我不确定这会产生多大的不同,但您可以阻止使用 set()eval()eval() 可以更改为 int(),因为您已经将 n = 设置为输入结果。接下来,您可以在 a 迭代时检查 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!")

【讨论】:

  • 以这种方式使用 10e6 运行大约需要 5 分钟左右,所以我想 10e10 需要一段时间。很长一段时间。
猜你喜欢
  • 2011-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-14
相关资源
最近更新 更多