分析涉及按位运算和 2 次幂的算法?

Posted

技术标签:

【中文标题】分析涉及按位运算和 2 次幂的算法?【英文标题】:Analyzing an algorithm involving bitwise operations and powers of two? 【发布时间】:2016-02-07 19:03:47 【问题描述】:

我编写了一个程序,计算给定输入数中 2 的最大幂。例如,数字 26 中 2 的最大幂是 16,因为 24 是 16。这是算法:

uint power2( uint n )

   uint i = n;
   uint j = i & (i - 1);
   while( j != 0 )
   
      i = j;
      j = i & (i - 1);
   
   return i;

我在算法分析方面有些吃力。我知道我们正在尝试找出 Big-Oh、Big-Omega 或 Big-Theta 符号。为了分析算法,我们应该计算基本操作的数量?我的问题是我看到两行可能是基本操作。我在 while 循环外看到了 uint j = i & (i - 1) 行,我还在 while 循环内看到了 j = i & (i - 1)。我感觉while循环里面的肯定是基本操作,但是while循环外面的呢?

我纠结的另一部分是确定while 循环的主体将执行多少次。例如,如果我们有一个 for 循环 for(int i = 0; i < n; i++) ...,我们知道这个循环将执行 n 次。甚至在一个while循环while(i < n * n) ... i++我们知道这个循环将运行n * n次。但是对于这个 while 循环,它会因输入而异。例如,如果你传入的数字是 2 的幂,那么 while 循环将永远不会执行。但是,如果你传入一个非常大的数字,它会执行很多次。老实说,我不知道它会执行多少次。这就是我想要弄清楚的。谁能帮我理解这个算法发生了什么以及它运行的次数,比如O(n)O(n^2)等?

【问题讨论】:

【参考方案1】:

这是一个很好的算法示例,当您对它的作用有很好的直观理解而不是仅仅通过查看代码本身时,更容易推理它。

首先,i & (i - 1) 是做什么的?如果你把一个二进制写的数字减去一个,它的效果是

清除最低有效 1 位,并 将之后的所有位设置为 1。

例如,如果我们将二进制数1001000 (72) 减去一,我们得到1000111 (71)。请注意最低有效位 1 是如何被清除的,并且所有低于该位的位都被设置为 1。

当您将号码 i 与号码 i - 1 相加时会发生什么?好吧,ii - 1 中最低有效 1 位以上的所有位都没有改变,但 ii - 1i 中最低有效 1 位或低于最低有效 1 位的所有位置上都不一致。这意味着i & (i - 1)具有清除数字i中最低1位的效果。

让我们回到代码。请注意,while 循环的每次迭代都使用此技术从数字j 中清除一个位。这意味着while循环的迭代次数与数字n中设置的1位数成正比。因此,如果我们让b代表n中设置的1位数,那么这个算法的运行时间就是Θ(b)。

如您所述,要了解该算法的最佳和最坏情况行为,如果 n 是 2 的完美幂,则运行时间为 O(1)。这和这将得到的一样好。在最坏的情况下,数字n 可能全为 1 位,在这种情况下,数字 n 中将设置 Θ(log n) 1 位(因为在二进制中,数字 n 需要 Θ(log n) 位写出来)。因此,最坏情况下的运行时间是 Θ(log n)。

总之,我们看到了

最佳情况下的运行时间是 O(1), 最坏情况下的运行时间是 Θ(log n),并且 确切的运行时间是 Θ(b),其中 b 是 n 中设置的位数。

【讨论】:

如果这没有得到 A 级那么我不知道会怎样:-) 我现在了解最佳情况下的运行时间是 O(1),但我仍然对最坏情况下的 Θ(log n) 感到困惑。你怎么知道是 log n? @GenericUser01 我们知道内循环的运行时间与数字中设置的1位的数量成正比。因此,如果我们选择一个每个位都设置为 1 的数字,那么对于给定的位数,运行时间将尽可能大。我们在这里得到对数项的原因是二进制数 111...11(k 次)表示数字 2^0 + 2^1 + 2^2 + ... + 2^k = 2^k+ 1 - 1。因此,设置了 k 位的数字的大小大约为 O(2^k),这意味着 n 的大小比设置的位数呈指数级大。反转指数给出对数项。 @GenericUser01 一般而言,任何对数字will have time complexity O(log n) 中的每个数字或位执行 O(1) 的算法,其中 n 是所讨论的数字。 @templatetypedef 为什么我们需要反转 O(2^k)?为什么这不是算法的大哦?我知道运行时间取决于设置为1 的位数。我仍然很难看到这是如何登录的。我查看了另一个链接和除以 2 直到你得到一个小于或等于 1 的数字的例子是有道理的,但在这里我很难看到。

以上是关于分析涉及按位运算和 2 次幂的算法?的主要内容,如果未能解决你的问题,请参考以下文章

幂的运算:X的n次幂

怎样算次幂啊

用Java计算x的y次幂x^y以及位运算计算2^n

《算法零基础100讲》(第50讲) 位运算 (按位取反)

位运算小结

位运算符和运算符优先级