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

C语言中用位表示整数集合:typedef实现及操作疑问

用位集合优化你的0-127整数集合实现

嘿,我来把位集合的思路掰碎了讲清楚,顺便给你写好核心操作的代码示例,解决你空间占用大的问题!

为什么位表示更省空间?

你现在用的char array[128]结构体,每个元素占1字节(8位),总共要128字节才能存0-127的存在标记。但其实我们只需要1位就能标记一个数是否在集合里——1表示存在,0表示不存在。128个数刚好需要128位,也就是16字节(128/8),空间直接缩小到原来的1/8,后续定义set_a、set_b这类集合时能省不少内存。

位集合的核心原理

把0-127每个整数对应到一个二进制位的位置:

  • 数字0 → 第0位
  • 数字1 → 第1位
  • ...
  • 数字127 → 第127位

我们可以用两个uint64_t(每个64位,刚好凑够128位)来存储这些位,位操作会更高效:

#include <stdint.h>
// 用两个64位无符号整数存128位,对应0-127的数
typedef uint64_t some_set[2];

基础位操作函数(添加、判断存在、删除)

先写几个辅助函数帮你操作单个元素:

// 向集合中添加数字n(n必须在0-127之间)
void add_to_set(some_set set, int n) {
    int idx = n / 64; // 确定是第一个还是第二个uint64_t
    int bit_pos = n % 64; // 确定在该uint64_t中的位位置
    set[idx] |= (1ULL << bit_pos); // 把对应位设为1
}

// 判断数字n是否在集合中
int is_in_set(some_set set, int n) {
    int idx = n / 64;
    int bit_pos = n % 64;
    return (set[idx] & (1ULL << bit_pos)) != 0;
}

// 从集合中删除数字n
void remove_from_set(some_set set, int n) {
    int idx = n / 64;
    int bit_pos = n % 64;
    set[idx] &= ~(1ULL << bit_pos); // 把对应位设为0
}

实现你需要的集合操作

接下来就是你要的print_set、union_set、intersect_set:

1. 打印集合

遍历0-127,把存在的数字打印出来:

#include <stdio.h>

void print_set(some_set set) {
    printf("{ ");
    int first = 1;
    for (int i = 0; i <= 127; i++) {
        if (is_in_set(set, i)) {
            if (!first) {
                printf(", ");
            }
            printf("%d", i);
            first = 0;
        }
    }
    printf(" }\n");
}

2. 求两个集合的并集

并集的规则是:只要其中一个集合有该数字,结果集合就包含它。对应位操作就是按位或(|):

void union_set(some_set result, some_set a, some_set b) {
    result[0] = a[0] | b[0];
    result[1] = a[1] | b[1];
}

3. 求两个集合的交集

交集的规则是:只有两个集合都有的数字,结果集合才包含它。对应位操作就是按位与(&):

void intersect_set(some_set result, some_set a, some_set b) {
    result[0] = a[0] & b[0];
    result[1] = a[1] & b[1];
}

测试示例

给你一个简单的测试代码,看看怎么用这些函数:

int main() {
    some_set set_a = {0}; // 初始化集合为空
    some_set set_b = {0};
    some_set set_union, set_intersect;

    // 给set_a添加元素
    add_to_set(set_a, 5);
    add_to_set(set_a, 10);
    add_to_set(set_a, 127);

    // 给set_b添加元素
    add_to_set(set_b, 10);
    add_to_set(set_b, 20);
    add_to_set(set_b, 127);

    // 打印原集合
    printf("set_a: ");
    print_set(set_a);
    printf("set_b: ");
    print_set(set_b);

    // 计算并集和交集
    union_set(set_union, set_a, set_b);
    intersect_set(set_intersect, set_a, set_b);

    printf("Union: ");
    print_set(set_union);
    printf("Intersect: ");
    print_set(set_intersect);

    return 0;
}

运行这段代码,输出会是:

set_a: { 5, 10, 127 }
set_b: { 10, 20, 127 }
Union: { 5, 10, 20, 127 }
Intersect: { 10, 127 }

是不是比原来的char数组方案高效多了?如果还有疑问随时问!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:07:14