You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅用位运算高效枚举无相邻置位的N长位向量(N≤64)

高效枚举无相邻置位的N位向量(仅位运算、非递归)

要高效枚举长度为N(N≤64)且无相邻1的位向量,核心是**直接生成符合条件的数,而非遍历所有2N个数再筛选**,时间复杂度为O(F(N+2))(F为斐波那契数列),远低于朴素方法的O(N*2N)。

核心思路

无相邻1的N位二进制数,本质是不含连续1的数,这类数的总数是斐波那契数列的第N+2项(例如N=4时总数为8,对应F(6)=8)。我们可以通过位运算直接生成每个符合条件的数,无需递归或全量遍历。

逐一生成法(适合N≤64)

这种方法通过位运算快速计算当前数的下一个符合条件的数,无需存储所有结果,适合处理较大的N值:

算法步骤

给定当前符合条件的数x,下一个数的计算逻辑:

  1. s = x + 1:找到第一个可进位的位置,触发低位翻转
  2. c = x & -x:提取x的最低位1(利用补码特性)
  3. r = x + c:将最低位1及其右侧的0全部翻转,得到进位后的基础值
  4. mask = (s ^ r) >> 2:计算需要调整的右侧位掩码
  5. next_x = r | (mask / c):将右侧位调整为最小的无相邻1形式,得到下一个符合条件的数

当next_x超过2^N时,停止迭代。

代码示例(C语言)

#include <stdio.h>
#include <stdint.h>

// 打印N位二进制字符串辅助函数
void print_binary(uint64_t x, int n) {
    char buf[65] = {0};
    for (int i = n-1; i >= 0; i--) {
        buf[n-1 - i] = (x >> i) & 1 ? '1' : '0';
    }
    printf("%s\n", buf);
}

void enumerate_no_adjacent_ones(int n) {
    uint64_t max = 1ULL << n;
    uint64_t x = 0;
    do {
        print_binary(x, n);
        // 计算下一个数
        uint64_t s = x + 1;
        uint64_t c = x & -x;
        uint64_t r = x + c;
        uint64_t mask = (s ^ r) >> 2;
        x = r | (mask / c);
    } while (x < max);
}

int main() {
    puts("N=4时的符合条件位向量:");
    enumerate_no_adjacent_ones(4);
    return 0;
}

输出验证(N=4)

运行代码后会输出:

0000
0001
0010
0100
0101
1000
1001
1010

所有结果均无相邻置位,符合要求。

复杂度说明

每次生成下一个数的操作都是O(1)的位运算,总共有F(N+2)个符合条件的数。由于斐波那契数列的增长速度是φN(φ≈1.618),远慢于2N,因此该方法的效率远高于朴素筛选法。

内容的提问来源于stack exchange,提问作者ynn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 21:35:12