zoukankan      html  css  js  c++  java
  • [笔记]利用二进制数进行集合运算

    二进制数可方便进行集合的表示与运算

    一、如何表示集合

    二进制数的每一位代表了此处的开关状态,以此来表示集合中元素的有无。
    一些特殊集合的表示:全集 2^n-1, 空集 0 。

    1.如何向集合中插入元素

    若要插入第 n 号元素,只需向代表集合的二进制数加上 2^n 即可。

    2.如何读取集合中元素的有无

    只需将二进制数按位与 1<<n。结果若为 1,即有元素;为 0,即无元素。
    遍历集合中的各元素只需每位按位与。


    二、位运算与集合运算

    利用位运算可方便快速的进行集合运算。

    A B A&B A|B A^B
    二进制 10110 01100 00100 11110 11010
    集合 {1, 2, 4} {2, 3} {2} {1, 2, 3, 4} {1, 3, 4}
    操作 取交集 取并集 对称差

    利用位运算还可简单实现取子集。


    三、示例

    #include <cstdio>
    const int n=5;
    void output(int set){
        for (int i=0; i<5; i++)
    	if (set & (1<<i)) printf("%d ", i+1);
        printf("
    ");
    }
    
    int main(void){
        int A=22, B=12, U=(1<<n)-1;//A{2, 3, 5} B{3, 4}
        
        printf("集合A: ");
        output(A);
        printf("集合B: ");
        output(B);
        printf("A&B: ");
        output(A&B);
        printf("A|B: ");
        output(A|B);
        printf("A^B: ");
        output(A^B);
        printf("A的补集: ");
        output(U^A);
        printf("
    A的所有子集: 
    ");
        //取子集操作
        for (int s=(A-1)&A; s!=0; s=(s-1)&A) output(s);
        printf("全集的所有子集:
    ");
        for (int i=1; i<U; i++) output(i);
    
        return 0;
    }
    

    输出结果:

    集合A: 2 3 5 
    集合B: 3 4 
    A&B: 3 
    A|B: 2 3 4 5 
    A^B: 2 4 5 
    A的补集: 1 4 
    
    A的所有子集: 
    2 3 5 
    3 5 
    2 5 
    5 
    2 3 
    3 
    2 
    全集的所有子集:
    1 
    2 
    1 2 
    3 
    1 3 
    2 3 
    1 2 3 
    4 
    1 4 
    2 4 
    1 2 4 
    3 4 
    1 3 4 
    2 3 4 
    1 2 3 4 
    5 
    1 5 
    2 5 
    1 2 5 
    3 5 
    1 3 5 
    2 3 5 
    1 2 3 5 
    4 5 
    1 4 5 
    2 4 5 
    1 2 4 5 
    3 4 5 
    1 3 4 5 
    2 3 4 5 
    1 2 3 4 5 
    

    四、二进制表示集合的缺点及解决方法

    1.数据范围小

    可以知道最大范围的数据类型为64位的 long long, 一共可以表示64个元素。那么如果总元素大于64呢?

    解决方法

    利用数组可以简单解决取交集、并集、对称差,也可解决取子集问题。
    取交集、并集、对称差 可以用数组中每一数进行位运算;
    取子集 可每次先按数组中最高一位数取子集,后找低一位数的子集(类似dfs)。

  • 相关阅读:
    SQL Server 日期函数:某天是星期几?
    DZNEmptyDataSet,优秀的空白页或者出错页封装
    SVN文件排除
    Android开发艺术探索读书笔记——进程间通信
    HDU 2110 Crisis of HDU
    Android4.4之后休眠状态下Alarm不准时的问题
    Android App性能測试
    Java笔试面试题整理第一波
    美国大学计算机专业
    js 開始时间,当前时间,结束时间的比較
  • 原文地址:https://www.cnblogs.com/tanglizi/p/7707759.html
Copyright © 2011-2022 走看看