-
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上的第几个bit i&0x1F是i/32的余数 for (i = 0; i < N; i++) clr(i);每位设为0, while (scanf("%d", &i) != EOF) set(i); 从读入获取数据,对应的位置为1 for (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...
而是按位与,如:
i=10,i & MASK => 10 & 31 => 0b1010 & 0b11111 => 0b11010 => 26