【问题标题】:How do I find the space and time complexities for this code如何找到此代码的空间和时间复杂度
【发布时间】:2020-12-22 21:15:43
【问题描述】:
fun root(n) =
if n>0 then
let
  val x = root(n div 4);
in
  if (2*x+1)*(2*x+1) > n then 2*x
  else 2*x+1
end
else 0;

fun isPrime(n,c) =
if c<=root(n) then
  if n mod c = 0 then false
  else isPrime(n,c+1)
else true;

这里的 root(n) 函数的时间复杂度是 O(log(n)):数字在每一步都除以 4,函数本身的代码是 O(1)。 isPrime 函数的时间复杂度为 o(sqrt(n)),因为它从 1 迭代运行到 sqrt(n)。我现在面临的问题是这两个函数的顺序是什么?它只是 O(sqrt(n)) 还是 O(sqrt(n)*log(n)) 或其他什么?

总的来说,我是大 O 表示法的新手,我浏览了多个网站和 youtube 视频,试图理解这个概念,但我似乎无法自信地计算它......如果你们能指出我一些资源可以帮助我练习计算,这将是一个很大的帮助。

【问题讨论】:

  • 这能回答你的问题吗? Big O of Recursive Methods
  • @SimonShine 是的,谢谢,我将不得不花更多的时间来理解主定理,乍一看似乎很有帮助......你能确认一下代码的顺序吗不过我发了?

标签: big-o sml


【解决方案1】:

root(n)O(log₄(n)),是的。

isPrime(n,c)O((√n - c) · log₄(n))

  • 您在每一步都重新计算root(n),即使它从未改变,导致“...·log₄(n)”。
  • 您将c 从某个值迭代到root(n);虽然它以root(n) 为上界,但不是下界:c 可以从 0 开始,或者从任意大的负数开始,或者从小于或等于 √n的正数开始>,或大于 √n 的数字。如果您假设c 从 0 开始,那么 isPrime(n,c)O(√n · log₄(n))

您可能希望使用归纳法或参考主定理来证明这一点。您可能希望简化 isPrime,使其不会将 c 作为其外部签名中的参数,并且不会在每次迭代时不必要地重新计算 root(n)

例如:

fun isPrime n =
    let
      val sq = root n
      fun check c = c > sq orelse (n mod c <> 0 andalso check (c + 1))
    in
      check 2
    end

这个isPrime(n)O(√n + log₄(n)),或者如果我们省略低阶项,则只是O(√n)。 p>

首先它在O(log₄(n))处计算root n一次

然后它在O(√n)处从0循环到root n一次

请注意,目前我们都没有正式证明任何事情。

编辑:已将 check (n, 0) 更改为 check (n, 2),因为废话。)

编辑:n 作为参数从 check 中删除,因为它永远不会改变。)

(编辑:正如你所指出的,Aryan 从 2 循环到 root n 确实是 O(√n),即使计算 root n只需要 O(log₄(n))!)

【讨论】:

  • 我将 c 保留为原样,因为我实际上将它用作更大算法中的辅助函数。我真的很喜欢你对支票的实施,尽管谢谢你。我不明白的是,在我的 isPrime 函数中,我从 2 迭代到 root(n) (我将 c 初始化为 2)所以不应该花费 O(root(n)) 时间吗?
  • 啊,听起来你可以从某个点开始使用检查。聪明的。 :-) 我只是在考虑证明和通常保持接口最小化的优点/缺点。回答您的问题:是的,它应该。但是您在每次迭代中调用一次root(n)。这相当于 C 代码 for (int i = 0; i &lt; expensiveOperation(); i++)for (int i = 0, max = expensiveOperation(); i &lt; max; i++)
  • 对,我明白了。但是仍然在您拥有的代码中,从 0 到 root(n) 的循环应该采用 O(root(n)) 复杂度,不是吗?
  • 我的回答不同意吗? (我将 0 固定为 2,这是我的错误。)如果“root(n)O(log₄(n))”,那么不应该调用 @987654347 的函数@ 的时间复杂度也有一个术语,也是 O(log₄(n))?我不确定您的问题是针对“root(n)”还是“log₄(n)”的措辞。
  • 对不起,这似乎是一个误解......你的 isPrime 函数应该有一个 O(√n) 的顺序,不是吗?因为它从 2 迭代到 √n?根据我到目前为止的研究,O(log n) 可以忽略,因为 √n > log n...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-17
  • 2012-08-14
相关资源
最近更新 更多