对于以下代码片段,N的增长顺序是什么?
int sum = 0;
for (int i = 1; i <= N; i = i*2)
for (int j = 1; j <= N; j = j*2)
for (int k = 1; k <= i; k++)
sum++;
我认为有lgN术语,但我仍然坚持评估这部分:lgN(1 + 4 + 8 + 16 + ....)。序列的最后一项是什么?我需要最后一个术语来计算总和。
答案 0 :(得分:3)
你的外部循环中有一个几何级数,因此有一个封闭的形式表示你要记录日志的总和:
avcodec_open2()
准确地说,你的总和是
1 + 2 + 4 + ... + 2^N = 2^(N+1) - 1
,1 + ... + 2^(floor(ld(N))
表示基数为2的对数。
外部两个循环彼此独立,而最内层循环仅依赖于ld
。最内层循环中有一个操作(增量),这意味着对最内层循环的访问次数等于求和结果。
i
这相当于 \sum_i=1..( floor(ld(N)) ) {
\sum_j=1..( floor(ld(N)) ) {
\sum_k=1..2^i { 1 }
}
}
// adjust innermost summation bounds
= \sum_i=1..( floor(ld(N)) ) {
\sum_j=1..( floor(ld(N)) ) {
-1 + \sum_k=0..2^i { 1 }
}
}
// swap outer summations and resolve innermost summation
= \sum_j=1..( floor(ld(N)) ) {
\sum_i=1..( floor(ld(N)) ) {
2^i
}
}
// resolve inner summation
= \sum_j=1..( floor(ld(N)) ) {
2^(floor(ld(N)) + 1) - 2
}
// resolve outer summation
= ld(N) * N - 2 * floor(ld(N))
(表达式中的第二项渐渐消失为第一项)以Big-Oh表示法。
答案 1 :(得分:0)
根据我的理解,外部循环将采用log N
步骤,下一个循环也将采用log N
步骤,最内层循环将采用最多N
步骤(尽管这是一个非常粗略的界限)。总的来说,循环的运行时复杂度最多为((log N)^2)*N
,这可能会得到改善。