【问题标题】:Find a block of continuous set/unset bits查找连续设置/未设置位块
【发布时间】:2015-10-14 19:04:09
【问题描述】:

我正在寻找一种方法来在 bitset 中找到连续的 set 或 unset 位块,例如在 bitset 01010111010 如果我正在寻找 3 个 set 位,我想得到 6 个结果(从1,如果我从 0 开始计数,则为 5)。

另外,这是针对 OS-dev 的,所以没有 stdlib 可以为我做这件事。

【问题讨论】:

  • 如果是1110111011呢?
  • 那我真的不在乎我会得到哪一个。我对内存中的已分配/空闲页面使用位集,有时我需要例如 3 页连续内存,所以我需要找到 3 个连续设置位。
  • 请详细说明。你的情况如何?什么数据类型?你尝试了什么?
  • 数据类型是一个 uint32_t 数组,其中 32 个,总和为 1024 位。我试图找到第一个 1,然后从那里数下一个 1,如果它们还不够,请返回,找到下一个 1,从那里数,但这似乎完全愚蠢且效率低下。跨度>
  • 我投票重新打开这个问题,因为链接副本上接受的答案是带有场外链接的 C/C++ 库推荐,这应该是题外话,并且这个问题也被标记为 C

标签: c operating-system bitset


【解决方案1】:

这是一个 N 阶方法,最好用一个例子来描述。

假设你的号码是 x。

要找到 3 个连续的 1 位,从 n = 7 开始。(即 0b111。)计算 x & n。如果那是 x,那么你的数字末尾有 3 个连续的 1 位。

如果不是按位移 n 得到 0b1110。再次计算 x & n。

继续直到达到(并测试)x 中最重要的 1 位。

也许有更有效的方法,例如覆盖 0b1110111,这将需要更少的班次,但成功的表达式更复杂。

【讨论】:

    【解决方案2】:

    无需代码,但有一种方法:创建一个移位寄存器来保存您要计算的位数,然后将您的比特流转移到它(使用计数器跟踪)。如果你的移位寄存器保存所有的,你就完成了。然后计数器将成为该位置。

    请注意,大多数计算机使用 little-endian 表示法,因此您必须进行一些移位、复制等操作才能创建您的比特流。

    【讨论】:

    • 移位寄存器是指最后设置的 x 位,其中 x 是我需要的设置位数?听起来不错
    • @tkausl 这可能是一个实现,是的
    【解决方案3】:

    假设您正在寻找整数 n 中的 3 个连续位。

    首先,将其自身向右移动 1 位和 2 位的值按位与:

    n = n & (n >> 1) & (n >> 2);
    

    现在只设置 3 个连续位序列的开始位(从 LSB 开始)。

    如果您需要连续检查超过 3 个,您可以在一个循环中针对任意(但很小)的运行长度执行此操作。

    然后,使用快速位操作algorithm 来计算二进制数中的尾随零,找到设置的第一位(从最低有效位开始计数为位 0)。

    使用这种方法,您只需使用几个操作即可一次搜索 32 位或 64 位。但是,如果您正在查看 32 位或 64 位整数的字符串,它会变得更加复杂,但是您可以对每个单词重复该过程,在第一步中从下一个 int 移入低位。

    如果您要查找的连续位数很大,这也不是最佳选择。

    【讨论】:

    • 这实际上是一个非常好的方法,非常感谢那个链接!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多