#include <stdio.h>
int main() {
int N = 8; /* for example */
int sum = 0;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= i*i; j++)
sum++;
printf("Sum = %d\n", sum);
return 0;
}
对于每个n值(i变量),j值将为n ^ 2。所以复杂性将是n。 n ^ 2 = n ^ 3。这是对的吗?
如果问题变成:
#include <stdio.h>
int main() {
int N = 8; /* for example */
int sum = 0;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= i*i; j++)
for (int k = 1; k <= j*j; k++)
sum++;
printf("Sum = %d\n", sum);
return 0;
}
然后你使用现有的n ^ 3。 n ^ 2 = n ^ 5?这是对的吗?
答案 0 :(得分:4)
我的点数为i
,j < i*i
和k < j*j
x^1 * x^2 * (x^2)^2 = x^3 * x^4 = x^7
。
特别是,因为1 < i < N
我们有i
循环的O(N)。由于1 < j <= i^2 <= N^2
我们有第二个循环的O(n ^ 2)。扩展逻辑,我们为第三个循环1 < k <= j^2 <= (i^2)^2 <= N^4
。
内部到外部循环,我们为每个N^4
循环执行最多j
次,每个N^2
循环最多执行i
次,最多{N
次在i
循环上1}}次,使得总数为N^4 * N^2 * N = N^7
= O(N^7)
。
答案 1 :(得分:1)
对于i = 1
内循环运行1^1
次,i = 2
内循环运行2^2
次......和i = N
内循环运行{{ 1}}次。其复杂度为N^N
的{{1}}。
在第二种情况下,对于1^1 + 2^2 + 3^3 + ...... + N^N
,第一内循环迭代O(N^3)
次,因此第二内循环(最内循环)将迭代最多i = N
次。因此,复杂性为N^N
,即N * (N^N) * (N^N)
。
答案 2 :(得分:1)
我认为复杂性实际上是O(n ^ 7)。
第一个循环执行N个步骤。 第二个循环执行N ^ 2步。
在第三个循环中,j * j可以达到N ^ 4,因此它具有O(N ^ 4)复杂度。
总的来说,N * N ^ 2 * N ^ 4 = O(N ^ 7)答案 3 :(得分:0)
是。在第一个示例中,i
循环运行N
次,内部j
循环调整i*i
次,即O(N^2)
。所以整件事是O(N^3)
。
在第二个示例中,还有一个额外的O(N^4)
循环(循环到j*j
),因此它总体上为O(N^5)
。
要获得更正式的证明,请计算sum++
执行N
次的次数,并查看N的最高多项式次序。在第一个示例中,它将是{{1 (对于a(N^3)+b(N^2)+c(N)+d
,a
,b
和c
的某些值,所以答案是3。
注意:编辑重新举例2说它是O(N ^ 4):d
误读了i*i
。
答案 4 :(得分:0)
考虑所有循环的调用次数。
int main() {
int N = 8; /* for example */
int sum = 0;
for (int i = 1; i <= N; i++) /* Called N times */
for (int j = 1; j <= i*i; j++) /* Called N*N times for i=0..N times */
for (int k = 1; k <= j*j; k++) /* Called N^2*N^2 times for j=0..N^2 times and i=0..N times */
sum++;
printf("Sum = %d\n", sum);
return 0;
}
因此sum ++语句被称为O(N ^ 4)* O(N ^ 2)* O(N)次= O(N ^ 7),这就是程序的整体复杂性。
答案 5 :(得分:0)
解决这个问题的不正确方法(虽然常见,并且经常给出正确答案)是近似内部循环的最大迭代次数与最坏情况。这里,内环在最坏的情况下循环O(N ^ 4),中间循环在最坏的情况下循环O(N ^ 2)次,外循环循环O(N)次,给出(偶然正确)O的解( N ^ 7)将它们相乘。
正确的方法是从内到外工作,小心谨慎地明确所接近的内容。
增量指令的总迭代次数T与您的代码相同。把它写出来:
T = sum(i=1..N)sum(j=1..i^2)sum(k=1..j^2)1.
最里面的总和只是j ^ 2,给出:
T = sum(i=1..N)sum(j=1..i^2)j^2
由j索引的总和是连续整数的平方和。我们可以精确计算:sum(j = 1..n)j ^ 2是n *(n + 1)*(2n + 1)/ 6。设置n = i ^ 2,我们得到
T = sum(i=1..N)i^2*(i^2+1)*(2i^2+1)/6
我们可以通过使用连续整数的6次,4次和2次幂的和的公式来继续计算确切的答案,但这是一种痛苦,而且对于复杂性我们只关心i的最高功率。所以我们可以近似。
T = sum(i=1..N)(i^6/3 + o(i^5))
我们现在可以使用该和(i = 1..N)i ^ p = Theta(N ^ {p + 1})来得到最终结果:
T = Theta(N^7)