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

 

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上的第几个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...
    注意:MASK=0x1F=0b11111=31,不是32,i & MASK不是表示i%31,
    而是按位与,如:
    i=10,i & MASK => 10 & 31 => 0b1010 & 0b11111 => 0b11010 => 26
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
优化这段代码<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>图书购物车</title> <style> </style> <script src="js/vue.js"></script> </head> <body> <div id="demo"> <table border="1"> <tr> <td></td> <td>书籍名称</td> <td>出版日期</td> <td>价格</td> <td>购买数量</td> <td>操作</td> </tr> <tr> <td></td> <td>{{books1.name}}</td> <td>{{books1.date}}</td> <td>¥{{books1.price}}</td> <td><button @click="down(books1)">-</button>{{books4.count}}<button @click="up(books1)">+</button></td> <td><button @click="del">移除</button></td> </tr> <tr> <td></td> <td>{{books2.name}}</td> <td>{{books2.date}}</td> <td>¥{{books2.price}}</td> <td> <button @click="down(books2)">-</button>{{books4.count}}<button @click="up(books2)">+</button> </td> <td><button @click="del">移除</button></td> </tr> <tr> <td></td> <td>{{books3.name}}</td> <td>{{books3.date}}</td> <td>¥{{books3.price}}</td> <td> <button @click="down(books3)">-</button>{{books4.count}}<button @click="up(books3)">+</button> </td> <td><button @click="del">移除</button></td> </tr> <tr> <td></td> <td>{{books4.name}}</td> <td>{{books4.date}}</td> <td>¥{{books4.price}}</td> <td> <button @click="down(books4)">-</button>{{books4.count}}<button @click="up(books4)">+</button> </td> <td><button @click="del">移除</button></td> </tr> </table> <div>总价: ¥{{sum}}</div> </div> <!-- js部分 --> <script> const vm = new Vue({ el: "#demo", data: { books1: { name: '《算法导论》', date: '2006-9', price: 85.00, count: 1 }, books2: { name: '《UNIX编程艺术》', date: '2006-2', price: 59.00, count: 1 }, books3: { name: '《编程珠玑》', date: '2008-10', price: 39.00, count: 1 }, books4: { name: '《代码大全》', date: '2006-3', price: 128.00, count: 1 } }, computed: { sum () { return this.books1.price * this.books1.count + this.books2.price * this.books2.count + this.books3.price * this.books3.count + this.books4.price * this.books4.count } }, methods: { down (books1) { this.books1.count = books1.count - 1; } } }) </script> </body> </html>
最新发布
04-21

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值