值增加2的幂的循环的时间复杂度

时间:2019-12-08 11:40:10

标签: algorithm math time-complexity exponentiation

for(i=1;i<=n;i=pow(2,i)) { print i }

时间的复杂度是多少?

kth的近似i项将是pow(2,(pow(2,pow(2,pow(2, pow(2,pow(2,...... k times)))))))

如何将kth value of i < n的上述值k求解。

2 个答案:

答案 0 :(得分:2)

您所拥有的与tetration(2,n)类似,但是由于您输入了错误的结束条件而没有。

复杂度在很大程度上取决于域和实现。从您的示例代码中,我推断出真实域整数

此函数的增长非常快,因此经过5次迭代后,您需要bigints,即使+,-,*,/,<<,>>也不是O(1)。 pow和print的实施也有很大的影响。

如果n<tetration(2,4)小,则可以假设复杂度为O(1),因为对于这样小的n,没有渐近线可言。

请注意,pow在大多数语言中都是浮点,并且可以将2 by i的强大功能转换为简单的位移,所以我们假设:

for (i=1;i<=n;i=1<<i) print(i); 

我们可以使用i的先前状态来计算1<<i,如下所示:

i0=i; i<<=(i-i0); 

但是在这么大的数字上并没有加速。

现在,十年print(i)的复杂性是以下之一:

O( log(i))               // power of 10 datawords (like 1000000000 for 32 bit)
O((log(i))^2)            // power of 2 datawords naive print implementation
O( log(i).log(log(i)))   // power of 2 datawords subdivision or FFT based print implementation

移位1<<i和比较i<=n的复杂度是:

O(log(i))                // power of 2 datawords

因此,以2个数据字的幂为print选择最佳实现会导致迭代:

O( log(i).log(log(i) + log(i) + log(i) ) -> O(log(i).log(log(i)))

乍一看,人们会认为我们需要知道k的迭代次数n

n = tetration(2,k)
k = slog2(n)

Knuth's notationAckermann function直接相关:

n = 2↑↑k
k = 2↓↓n

但是,与循环内部内容的内部复杂度相比,迭代次数非常少,下一次迭代增长得如此之快,以至于上一次迭代可以忽略下一次迭代的一部分,因此我们可以忽略它们,而只考虑最后一个/迭代...

所有这些假设之后,我得到了最终的复杂性:

O(log(n).log(log(n)))

答案 1 :(得分:0)

在每次迭代中,您的幂为std::string

让log ^ {k}(n)是对n应用k次的对数函数。例如,log ^ {1}(n)= log(n),而log ^ {2}(n)= log(log(n))。

在此表示法下,您的算法的运行时间为log ^ {k}(n)。

相关问题