a[i>>SHIFT] |= (1<<(i & MASK)) 编程珠玑

来源:互联网 发布:程序调试软件测试 编辑:程序博客网 时间:2024/04/29 16:00

 

2011-04-17 22:43:54|  分类:c |  标签:mask  int  ishift  define  bitsperword  |字号 订阅


C/C++ code
/* Copyright (C) 1999 Lucent Technologies */ /* From 'Programming Pearls' by Jon Bentley */ /* bitsort.c -- bitmap sort from Column 1 * Sort distinct integers in the range [0..N-1] */ #include <stdio.h> #define BITSPERWORD 32 #define SHIFT 5 #define MASK 0x1F #define N 10000000 int a[1 + N/BITSPERWORD]; void set(int i) { a[i>>SHIFT] |= (1<<(i & MASK)); } void clr(int i) { a[i>>SHIFT] &= ~(1<<(i & MASK)); } int test(int i){ return a[i>>SHIFT] & (1<<(i & MASK)); } int main() { int i; for (i = 0; i < N; i++) clr(i); /* Replace above 2 lines with below 3 for word-parallel init int top = 1 + N/BITSPERWORD; for (i = 0; i < top; i++) a[i] = 0; */ while (scanf("%d", &i) != EOF) set(i); for (i = 0; i < N; i++) if (test(i)) printf("%d\n", i); return 0; }
1.
void set(int i) { a[i>>SHIFT] |= (1<<(i & MASK)); }里面,
a[i>>SHIFT]是第i位应该在第几个int上  (1<<(i & MASK))是第i位在该int上的第几个biti&0x1F是i/32的余数for (i = 0; i < N; i++)         clr(i);每位设为0,while (scanf("%d", &i) != EOF)         set(i);从读入获取数据,对应的位置为1for (i = 0; i < N; i++)         if (test(i))             printf("%d\n", i);     return 0;遍历所有位,则输出自然有序 
2.
对,左移5位相当于除2^5也就是32,i & 0x1F 保留了低五位,相当于模32.
i是int类型,32位的,而a是int型数组,所以除以32可以知道是在a的数组中哪一个下标,模32可以确定某一位。
3.
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
#define N 10000000
int a[1 + N/BITSPERWORD];

void set(int i) { a[i>>SHIFT] |= (1<<(i & MASK)); } //就是将指定的bit赋1
void clr(int i) { a[i>>SHIFT] &= ~(1<<(i & MASK)); } //就是将指定的bit清0
int test(int i){ return a[i>>SHIFT] & (1<<(i & MASK)); } //就是取一下存入的值

是每5 bit是一组。
  while (scanf("%d", &i) != EOF)
  set(i);
根据输入的i ,放入指定位置。
作者的想法是,按照输入的数据,放入该数据的位置上。
比如你输入,4,2,3,1
那么第一个4就是
0000000000010000
而输入2的时候
0000000000010100
输入3时候
0000000000011100
输入1的时候
0000000000011110
 
然后从bit0~~~bit N判断该位是不是0,如果不是0的话,就为有数组,并作输出,相当排序。
 for (i = 0; i < N; i++)
  if (test(i)) //
  printf("%d\n", i);
4.
编程珠玑上的源代码。a[i>>SHIFT] |= (1<<(i & MASK))。我不知道1<<(i & MASK) 什么意思,i & MASK表示i%32,知道是要求哪一位,但为什么要1<<呢,左移一位干吗
               不是左移1位,而是1左移(i&mask)位,
               移完结果是0000x0000...
    注意:MASK=0x1F=0b11111=31,不是32,i & MASK不是表示i%31,
    而是按位与,如:
    i=10,i & MASK => 10 & 31 => 0b1010 & 0b11111 => 0b11010 => 26
原创粉丝点击