【问题标题】:Efficiency of searching a large list of numbers for certain digits在大量数字列表中搜索某些数字的效率
【发布时间】:2016-08-31 12:17:37
【问题描述】:

我有以下代码,其中eratosthenes(N) 返回一个从 1 到 N 的素数数组。我想要做的是从此列表中删除包含数字 0、2、4、5、6、8 的所有数字。我的代码似乎非常低效和错误,因为它需要大约 20 秒(eratosthenes(N) 是瞬时的)才能达到 100,000 并且不会删除我想要的所有数字。有没有更好的、可扩展的解决方案来解决这个问题?

N = 1_000_000
primes = eratosthenes(N)

primes.each do |num|
  if ["0", "2", "4", "5", "6", "8"].any? { |digit| num.to_s.include?(digit) }
      primes.delete(num)
  end
end

【问题讨论】:

  • "包含数字 0、2、4、5、6、8" - 我很确定这是高效 Eratosthenes 筛子的错误方法。您想跳过其 最后一个 数字是其中之一的数字,不是吗?
  • 另外,不要改变您当前正在迭代的数组。这应该解释“不会删除我想要的所有数字”
  • 我删除 0、2、4、5、6、8 的原因与我最初搜索素数的原因是分开的。我已经有了我的素数数组,我想进一步剔除它。第二点已适当注明。

标签: ruby performance scalability


【解决方案1】:

您的方法的问题是每个delete 都会重写数组,并为每个已删除的项目调用它,因此算法的复杂度是 O(n^2) 而不是 O(n)。

你应该这样做:

primes.reject!{|num| ["0", "2", "4", "5", "6", "8"].any? { |digit| num.to_s.include?(digit) }}

或者简单地说:

primes.reject!{|num| num.to_s[/[024568]/]}

这只是风格问题,但我会将所有内容放在一行中(注意此处reject 中缺少!):

primes = eratosthenes(N).reject{|num| num.to_s[/[024568]/]}

【讨论】:

  • 这似乎给了我两个不同的答案。如果我运行第一个,我的数组中剩下 1111 个素数,如果我运行第二个,我还剩下 3217 个素数。
  • 啊,抱歉,我没有注意到你的列表包括 5,我以为只有偶数。我已经编辑了我的答案,现在就试试吧。
【解决方案2】:

我应该认为您正在寻找类似的东西:

primes.reject!{|num| num % 2 == 0}

【讨论】:

  • 任务不是删除偶数(除 2 以外的素数都不是偶数),而是所有包含偶数的数字。
  • 这对我已经形成的素数列表没有任何作用,因为没有一个会被 2 整除。我正在寻找我的程序要做的是删除像 23、47、277 等这样的素数,因为它们分别有 2、4 和 2 个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-06
  • 2018-12-21
  • 2014-09-02
  • 1970-01-01
  • 2021-02-03
  • 1970-01-01
  • 2019-10-09
相关资源
最近更新 更多