【问题标题】:Time Complexity of bit operations位操作的时间复杂度
【发布时间】:2013-06-04 10:23:13
【问题描述】:

由于一些原始研究和开发工具的需要,我想出了一些新的,我希望更好/更快的方法来执行某些数学运算。 Atm 我正在处理伪代码以将它们发布在网站上,以回答已经提出的问题。

但是在我这样做之前,我想尽可能地优化它们,所以我需要有人从时间复杂度的角度来阐明位操作的工作原理。

例如,假设我想评估两个 8 位整数中哪个更大。我以 8 位为例,但实际上它们可能要大得多。

10000100

10100000

就目前而言,可以通过比较 6 个 MSB 来评估关系运算符。 理论上我可以从两者中减去 10000000 而不会影响不等式。

00100000

00000100

  • 第一季度。这将加快关系运算符的评估,如果 读数从 MSB 开始,但会执行或执行前导 0 无论如何都必须评估?明显的减法不值得做 因为减去 10000000 本身就是一个 8 位运算,但是说 相反,我可以使用一个或两个设置 MSB 或特定位 位操作,那么它可能是值得的。
  • 第二季度。我能想到的两种可能符合要求的方法是 向左移动然后向右移动以破坏前导 1 或使用 一个面具,但还有其他方法吗?我特别感兴趣 那些可能让你设置任何位的,而不仅仅是前导位。如果 它特定于某种语言,请告诉我。
  • 第三季度。由于掩码是 N 位,因此使用掩码而不是 N 位 操作本身?
  • 第四季度。如何评估特定位,存在哪些方法以及 操作的时间复杂度如何?是否所有进行的位都必须 先读入,这样它是一个 N 位操作,或者你可以“跳转” 到一定程度?
  • Q5 两个字符串从时间复杂度共轭 看法。通过关联两个内存地址是否会发生这种情况 在一起还是一个字符串被读取并复制到另一个字符串中 这是一个 String.length 操作?

谢谢。

进一步澄清。 我一直在重读我从几个地方提取的笔记,尽管杜克林证实了我认为应该是这样的情况,但我需要三重检查。以简单的乘法算法为例。我在许多地方看到声称这是一个 Log^2(N) 操作,并且它是一个 Log^2(N) 操作的给定原因是由于它由 Log(N) 添加一个 Log(N)数字。我遇到的问题是,虽然这是真的,但它忽略了这样一个事实,即每个 Log(N) 数字都是位移的结果,到最后我们将至少位移 Log(N) 次。由于位移 1 是一个 Log(N) 操作,因此单独考虑的位移会给我们 Log^2(N) 操作。因此,当我看到它进一步声称实际上乘法实际上并不使用 Log^2(N) 运算时,这对我来说毫无意义,因为各种方法可以减少所需加法的数量。由于单独的位移给了我们 Log^2(N) 我对这种说法是如何正确的感到困惑。

【问题讨论】:

  • 恭喜你提出了几十年来数百万人错过的东西......有一个问题:ACM(或类似的)通讯不是更合适的论坛吗?
  • @Mitch Wheat。我已经仔细检查并正确阅读了常见问题解答,这似乎是正确的论坛。根据它,这是“一个特定的编程问题,一种软件算法软件工具,程序员常用的实用、可回答的问题,是编程行业独有的”的地方。我认为我的问题在某些方面与此相符,所以我不理解降级。
  • @RhuaidhriTynan Communications of the ACM 与Stack Exchange 无关,我认为是where you were looking。我认为米奇说/暗示没有Stack Exchange 网站(或者更具体地说不是Stack Overflow(?))是合适的。我不太确定,我看到的唯一可能的问题是你不应该在一篇文章/问题中问 6 个问题。
  • 减法只需要 O(log n) 门延迟,所以看起来这比它的成本更有用。

标签: bit-manipulation big-o time-complexity masking bit-shift


【解决方案1】:
  1. 必须评估前导 0 位,除非您存储 MSB 的索引并编写自己的例程进行比较。

  2. 位移是一种 N 位操作。

  3. 屏蔽也是一个 N 位操作。

  4. 取决于您在内部如何表示它,跳转到正确的 字节 相对容易,但高级语言(如果您正在使用的话)通常不允许您要直接访问特定位,您需要一些操作(例如位移(仅该字节))来获取该位。

  5. 连接字符串需要 O(m+n),其中 m 和 n 是各个字符串的长度。我知道的所有字符串都在内存中按顺序表示。您也不一定可以在任何一个字符串之后访问内存(除非您通过分配足够的内存来强制执行此操作),因此必须将两者都复制到新位置。尽管没有什么能阻止您创建自己的数据结构。

所以...直接逐位或逐字节比较(可能使用 1 中提到的起始位置优化)可能是您将获得的最佳结果。

PS - 任何已发布的研究都应显示足够的证据(以某种形式)作为动机,说明为什么它比其他东西更好。

【讨论】:

  • 感谢 Dukeling 几乎为我解决了问题。鉴于这种情况,我不明白为什么这么多人似乎建议这些操作在使用到位或减法等时显着降低复杂性。只是为了仔细检查你所说的移位是 N 位在这种情况下是 N 位大小还是移位次数,在我的示例中,左右移位是 2 位还是 16 位(因为所有 8 位都必须双向移动,即使我们只将它们移动一个位置)。我将使用起始位置的想法,因为它似乎是减少逐位比较次数的最佳方法。
  • 按位运算(位移位、与、或、异或)比算术运算(加法、减法、乘法、除法)稍快,因为计算机的工作方式,但它们仍然是 N-位操作,并且使用按位操作通常是一种微优化(通常意味着不值得努力)。所有 8 位都必须移位,处理器不知道哪些位是 0,哪些是 1。
  • 用一个例子编辑了帖子,我希望你能澄清一下。谢谢。
  • 如果所有位都设置了,则有log^2 n位移,然后log n加法,导致O(log^2 n + log n) = O(log^2 n)。现在假设我们扫描一个数字 (O(log n)) 并看到只设置了一位。现在我们只需要一个班次 (O(log n)) 并且不需要加法,从而导致 O(2 log n) = O(log n) 的性能。我不确定实际发生了什么,但这是一种可能性。还有more complex multiplication algorithms,但这些可能太复杂而无法在二进制上更有效。
猜你喜欢
  • 2012-11-27
  • 2012-03-17
  • 2011-11-13
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
  • 2020-10-28
  • 2016-12-16
相关资源
最近更新 更多