《编程珠玑》一段代码看不懂,“a[i>>SHIFT] |= (1<<(i & MASK));”
哪位朋友可以帮我解释一下啊?
完整代码是这样子的,顺便问一下,C代码写成这样,得几年功力?
/* 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 10000000int 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;}void set(int i) { a[i/32] |= (1<<(i%32)); }void clr(int i) { a[i/32] &= ~(1<<(i %32)); }int test(int i){ return a[i/32] & (1<<(i %32)); }
[解决办法]
只要是2的倍数都可以这么玩
不用多少年功力,记住,2的倍数的乘除法用位移实现,会者不难,没点破之前是不是觉得很……哈哈
[解决办法]
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;
遍历所有位,则输出自然有序
[解决办法]
对,左移5位相当于除2^5也就是32,i & 0x1F 保留了低五位,相当于模32.
i是int类型,32位的,而a是int型数组,所以除以32可以知道是在a的数组中哪一个下标,模32可以确定某一位。
[解决办法]
#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);
太经典了!!!!!!!!!
C语言功力不需要很强,关键是想法太好了!!
[解决办法]
这代码好省啊