考虑这段代码
int sum = 0;
for( int i = 1; i <= n*n; i = i*2 ){
sum++ ;
}
如何对其进行快速正确的分析以获得最坏情况下运行时间的增长顺序?
将增量语句更改为i = i * 3
而不是i = i * 2
如何更改最坏情况下的运行时间?
我们的分析是否受到将比较运算符更改为<
而不是<=
的影响?
答案 0 :(得分:4)
实际上这个循环是无限循环。
i=0
i=i*2 //0*2=0
所以这个循环永远不会结束。让i=1
获得2的幂计数,直到n ^ 2不能求和。
答案 1 :(得分:4)
int sum = 0;
for( int i = 0; i <= n*n; i = i*2 ){
sum++ ;
}
就目前而言,这是一个永无止境的无限循环,因为i
永远不会改变。
由于复杂性仅针对算法定义,根据定义,算法应在有限的时间内终止,因此该片段未定义。
但是,如果您将代码更改为以下内容:
int sum = 0;
for( int i = 1; i <= n*n; i = i*2 ){
sum++ ;
}
我们可以分析如下复杂性:
让循环运行k - 1
次,并在kth
的{{1}}更新时终止。
由于冗余比不清楚更好,以下是正在发生的事情:
Init(1) - &gt; test(1) - &gt;循环(1)[i = 1] - &gt;
更新(2) - &gt; test(2) - &gt;循环(2)[i = 2] - &gt;
...
更新(k-1) - &gt; test(k-1) - &gt;循环(k-1)[i = 2 ^(k-2)] - &gt;
更新(k) - &gt; test(k) - &gt; STOP [测试失败,因为我变为2 ^(k - 1)]
i
表示Update(k)
更新(kth
。
因为,i = i * 2)
中的增量是i
循环中的增量(或等效地,在pth
之后),pth updation
的值将为i
},我们可以说在终止时:
2 ^ (p - 1)
详细说,我们已经在第k次更新时终止了。无论2 ^ (k - 1) > (n * n)
的价值是多少,它都会大于i
,或者我们会去(n * n)
循环。双方都kth
:
log base 2
这意味着 k ~ 2 * log(n)
为k
。
等效地,循环运行的次数为O(log(n))
。
您可以轻松地将此想法扩展到任何限制(例如n * n * n)和任何增量(i * 3,i * 4等)
使用O(log(n))
代替Big O
<
复杂度不受影响
答案 2 :(得分:-1)
任何循环,分析它。你必须看到两件事。将使其退出的条件,并将迭代应用于条件中使用的变量..
代码。当我从0变为n * n(n ^ 2)时,你会注意到循环停止。并且变量i正在增加,如i = i * 2。当我以这种方式增加i时,循环将运行log(n ^ 2)次。你可以通过获取n ^ 2的示例值(如128)来看到,然后逐个手动迭代。