首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

《编程珠玑》一段代码看不懂,“a[i>>SHIFT] |= (1<<(i & MASK));”,该怎么处理

2012-04-05 
《编程珠玑》一段代码看不懂,“a[iSHIFT] |(1(i & MASK))”哪位朋友可以帮我解释一下啊?完整代码是这样

《编程珠玑》一段代码看不懂,“a[i>>SHIFT] |= (1<<(i & MASK));”
哪位朋友可以帮我解释一下啊?
完整代码是这样子的,顺便问一下,C代码写成这样,得几年功力?

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 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;}


[解决办法]
翻译一下……

C/C++ code
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语言功力不需要很强,关键是想法太好了!!
[解决办法]
这代码好省啊

热点排行
Bad Request.