efficiently find the first element matching a bit mask

后端 未结 4 509
小蘑菇
小蘑菇 2020-12-15 07:57

I have a list of N 64-bit integers whose bits represent small sets. Each integer has at most k bits set to 1. Given a bit mask, I would lik

4条回答
  •  眼角桃花
    2020-12-15 08:47

    With precomputed bitmasks. Formally is is still O(N), since the and-mask operations are O(N). The final pass is also O(N), because it needs to find the lowest bit set, but that could be sped up, too.

    #include 
    #include 
    #include 
    #include 
    
      /* For demonstration purposes.
      ** In reality, this should be an unsigned long long */
    typedef unsigned char Thing;
    
    #define BITSPERTHING (CHAR_BIT*sizeof (Thing))
    #define COUNTOF(a) (sizeof a / sizeof a[0])
    
    Thing data[] =
    /****** index abcdef */
    { 0x0c /* 0   001100 */
    , 0x0a /* 1   001010 */
    , 0x08 /* 2   001000 */
    , 0x04 /* 3   000100 */
    , 0x02 /* 4   000010 */
    , 0x01 /* 5   000001 */
    , 0x10 /* 6   010000 */
    , 0x20 /* 7   100000 */
    , 0x00 /* 8   000000 */
    };
    
            /* Note: this is for demonstration purposes.
            ** Normally, one should choose a machine wide unsigned int
            ** for bitmask arrays.
            */
    struct bitmap {
            char data[ 1+COUNTOF (data)/ CHAR_BIT ];
            } nulmaps [ BITSPERTHING ];
    
    #define BITSET(a,i) (a)[(i) / CHAR_BIT ] |= (1u <<  ((i)%CHAR_BIT) )
    #define BITTEST(a,i) ((a)[(i) / CHAR_BIT ] & (1u <<  ((i)%CHAR_BIT) ))
    
    void init_tabs(void);
    void map_empty(struct bitmap *dst);
    void map_full(struct bitmap *dst);
    void map_and2(struct bitmap *dst, struct bitmap *src);
    
    int main (void)
    {
    Thing mask;
    struct bitmap result;
    unsigned ibit;
    
    mask = 0x38;
    init_tabs();
    map_full(&result);
    
    for (ibit = 0; ibit < BITSPERTHING; ibit++) {
            /* bit in mask is 1, so bit at this position is in fact a don't care */
            if (mask & (1u <data); idx++) {
            dst->data[idx] &= src->data[idx] ;
            }
    }
    
    void map_empty(struct bitmap *dst)
    {
    memset(dst->data, 0 , sizeof dst->data);
    }
    
    void map_full(struct bitmap *dst)
    {
    unsigned idx;
            /* NOTE this loop sets too many bits to the left of COUNTOF(data) */
    for (idx = 0; idx < COUNTOF(dst->data); idx++) {
            dst->data[idx] = ~0;
            }
    }
    

提交回复
热议问题