foo算法的复杂度

发布于 2024-10-16 11:50:44 字数 369 浏览 0 评论 0原文

我有这个问题无法解决。这个 foo 算法的复杂度是多少?

int foo(char A[], int n, int m){
  int i, a=0;
  if (n>=m)
    return 0;
  for(i=n;i<m;i++)
    a+=A[i]  
  return a + foo(A, n*2, m/2);
}

foo 函数的调用方式是:

foo(A,1,strlen(A));

so..我猜它是 log(n) * 内部 for 循环的东西..我不确定它是 log(n) 还是什么..

它可能是 log^2 的 theta (n)?

I have this problem that I can't solve.. what is the complexity of this foo algorithm?

int foo(char A[], int n, int m){
  int i, a=0;
  if (n>=m)
    return 0;
  for(i=n;i<m;i++)
    a+=A[i]  
  return a + foo(A, n*2, m/2);
}

the foo function is called by:

foo(A,1,strlen(A));

so.. I guess it's log(n) * something for the internal for loop.. which I'm not sure if it's log(n) or what..

Could it be theta of log^2(n)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

九公里浅绿 2024-10-23 11:50:44

这是主定理的一个很好的应用:

用 n 和 X = mn 重写:

int foo(char A[], int n, int X){
  int i, a=0;
  if (X < 0) return 0;
  for(i=0;i<X;i++)
    a+=A[i+n]  
  return a + foo(A, n*2, (X-3n)/2);
}

所以复杂度是

T(X, n) = X + T((X - 3n)/2, n*2)

注意到惩罚随着 X 的增加而随着 n 的增加而减少,

T(X, n) < X + T(X/2, n)

所以我们可以考虑复杂度

U(X) = X + U(X/2)

并将其插入到主定理中来找到U(X) = O(X) -->复杂度为 O(mn)

This is a great application of the master theorem:

Rewrite in terms of n and X = m-n:

int foo(char A[], int n, int X){
  int i, a=0;
  if (X < 0) return 0;
  for(i=0;i<X;i++)
    a+=A[i+n]  
  return a + foo(A, n*2, (X-3n)/2);
}

So the complexity is

T(X, n) = X + T((X - 3n)/2, n*2)

Noting that the penalty increases with X and decreases with n,

T(X, n) < X + T(X/2, n)

So we can consider the complexity

U(X) = X + U(X/2)

and plug this into master theorem to find U(X) = O(X) --> complexity is O(m-n)

∞梦里开花 2024-10-23 11:50:44

我不确定是否有一种“快速而肮脏”的方法,但你可以使用古老的数学方法。没有花哨的定理,只有简单的方程。

在第 k 级递归(k 从零开始)上,循环将进行 ~ n/(2^k) - 2^k 次迭代。因此,对于0 <= i <= lS = sum(n/2^i) - sum(2^i) >,其中 l 是递归深度。

l 大约为 log(2, n)/2(证明一下)。

S公式中的各部分分别进行变换,可得。

S = (1 + 2 + .. + 2^l)*n/2^l - (2^(l + 1) - 1) ~= 2*n - 2^(l + 1) ~= 2*n - sqrt(n)

由于除循环之外的每个其他语句只会重复 l 次,并且我们知道 l ~= log(2, n),因此不会影响复杂性。

所以,最终我们得到O(n)

I'm not sure if there's a 'quick and dirty' way, but you can use old good math. No fancy theorems, just simple equations.

On k-th level of recursion (k starts from zero), a loop will have ~ n/(2^k) - 2^k iterations. Therefore, the total amount of loop iterations will be S = sum(n/2^i) - sum(2^i) for 0 <= i <= l, where l is the depth of recursion.

The l will be approximately log(2, n)/2 (prove it).

Transforming each part in formula for S separately, we get.

S = (1 + 2 + .. + 2^l)*n/2^l - (2^(l + 1) - 1) ~= 2*n - 2^(l + 1) ~= 2*n - sqrt(n)

Since each other statement except loop will be repeated only l times and we know that l ~= log(2, n), it won't affect complexity.

So, in the end we get O(n).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文