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

整数的真后代数求解算法咨询

我明白你卡在这个真后代数的生成问题上了——其实核心是抓住二进制子集的本质,用位运算就能高效解决,完全不用逐个遍历小于原数的所有数。让我一步步给你讲清楚:

先明确真后代数的等价定义

根据你给出的数学定义,真后代数h'可以等价为:

  • h'是原数h的二进制子集:也就是h'的每一位1都对应h的某一位1(用位运算表示就是(h' & h) == h');
  • h' < h(排除原数本身)且h' != 0(保证至少有一个共同的1位)。

核心技巧:枚举二进制子集

最高效的方法是利用位运算直接生成h的所有非空真子集,经典的技巧是用current = (current - 1) & h来依次遍历所有子集。这个表达式的原理是:

  1. 每次current - 1会把最右边的1变成0,后面的0全变成1;
  2. 和h做按位与,会把那些超出h范围的1(也就是h中为0的位)清零,从而得到h的下一个合法子集。

我们只需要跳过初始的h本身,以及最后得到的0,剩下的就是所有真后代数。

C语言实现代码(直接输出版本)

这个版本简单直接,适合快速验证结果:

#include <stdio.h>

void print_proper_descendants(int h) {
    if (h == 0) {
        printf("No proper descendants (input is 0)\n");
        return;
    }
    printf("Proper descendants of %d (binary: %d):\n", h, h);
    int current = h;
    // 枚举所有子集,跳过原数和0
    while ((current = (current - 1) & h) != 0) {
        printf("%d (binary: %d)\n", current, current);
    }
}

int main() {
    print_proper_descendants(21); // 测试你给出的例子
    return 0;
}

运行后输出的结果正好和你给出的一致:

Proper descendants of 21 (binary: 10101):
20 (binary: 10100)
17 (binary: 10001)
16 (binary: 10000)
5 (binary: 101)
4 (binary: 100)
1 (binary: 1)

C语言实现代码(收集到数组版本)

如果需要把结果存起来供后续处理,可以用这个版本:

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

// 计算二进制中1的个数,用来确定数组大小
int count_set_bits(uint32_t h) {
    int count = 0;
    while (h) {
        count++;
        h &= h - 1; // 清除最右边的1
    }
    return count;
}

uint32_t* get_proper_descendants(uint32_t h, int* out_count) {
    if (h == 0) {
        *out_count = 0;
        return NULL;
    }
    int bit_count = count_set_bits(h);
    int total = (1 << bit_count) - 2; // 非空真子集数量:2^k - 2
    uint32_t* result = malloc(total * sizeof(uint32_t));
    if (!result) {
        *out_count = 0;
        return NULL;
    }
    int idx = 0;
    uint32_t current = h;
    while ((current = (current - 1) & h) != 0) {
        result[idx++] = current;
    }
    *out_count = idx;
    return result;
}

int main() {
    uint32_t h = 21;
    int count;
    uint32_t* descendants = get_proper_descendants(h, &count);
    
    printf("Proper descendants of %u:\n", h);
    for (int i = 0; i < count; i++) {
        printf("%u ", descendants[i]);
    }
    printf("\n");
    
    free(descendants); // 记得释放内存
    return 0;
}

Python版本(供参考)

如果用Python实现,思路完全一致,代码更简洁:

def generate_proper_descendants(h):
    if h == 0:
        return []
    descendants = []
    current = h
    while (current := (current - 1) & h) != 0:
        descendants.append(current)
    return descendants

print(generate_proper_descendants(21))  # 输出 [20, 17, 16, 5, 4, 1]

为什么这个方法高效?

这个方法的时间复杂度是O(2^k),其中k是原数h二进制中1的个数,这已经是最优的了——因为真后代数的总数就是2^k - 2,我们直接生成每个结果,没有多余的计算。相比遍历所有小于h的数(时间复杂度O(h)),这个方法在h很大但1的个数很少时,效率提升非常明显。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 04:52:32