位运算应用

 参考链接

 

http://www.cppblog.com/xiaoyisnail/archive/2009/09/19/96707.html

 

本文主要内容:

1.用实例说明位运算在整数运算替代中有的优化作用

 

几道算法题
1.判断给定的整数是不是2的整数次幂
2.求给定整数的二进制表示中1/0的个数

3.求给定整数的二进制表示的有效位数

4.求大于等于给定整数的最小的2的整数次幂

5.用+,-和位运算实现正整数除法和取模 

6.if和三目运算符

 

判断给定的整数是不是2的整数次幂

与运算

如:B1000是,1001不是

T = O(1)

//判断n是否是2的正整数幂 inline bool is_2exp(unsigned int n) { return !(n&(n-1)); }

 

求给定整数的二进制表示中1/0的个数

与运算

num0 = sum – num1;

T = O(m) m为1的个数

//计算n的二进制表示中1的个数 int count1(unsigned int n) { int r = 0; while(n) { n &= n-1; r++; } return r; }

 

求给定整数的二进制表示的有效位数

 移位

T = O(n) n为二进制位数

//求给定整数的二进制表示的位数,线性算法 int count_bit(unsigned int n) { int r = 0; while(n) { n>>=1; r++; } return r; }

 

求大于等于给定整数的最小的2的整数次幂

如:B1111的答案为B10000。

方法1:移位

T = O(m)+O(n) = O(n), m为1的个数, n为二进制位数

//求大于等于n的最小的2的正整数幂,方法1 //时间复杂度O(n的二进制位长度) unsigned int high_2exp_1(unsigned int n) { if(n<=1) return 1; if(is_2exp(n)) return n;//判断是否是2的整数次幂 unsigned int r = 1; while(n) { n >>= 1; r <<= 1; } return r; }

 

方法2:或运算 

T = O(m)  m为1的个数

//求大于等于n的最小的2的正整数幂,方法2 //计算时间与n的二进制表示中1的个数和位置有关,比方法1效率高 //最坏情况下的时间复杂度与方法1相同 unsigned int high_2exp_2(unsigned int n) { if(n<=1) return 1; while(!is_2exp(n)) { n |= n-1; n++; } return n; }

 

用+,-和位运算实现正整数除法和取模 

方法1:逐步减被除数 

int integer_div_0(int dividend, int divisor) { if(divisor == 0) { cout<<“非法参数,除零错”<<endl; exit(1); } int res = 0; while((dividend-=divisor)>=0) ++res; return res; }

方法2:以2倍逐步增加被减数大小

如:100/13

100-13>0,100-2*13>0,100-4*13>0,100-8*13<0 商:4

100-4*13=48,48-13>0,48-2*13>0,48-4*13<0 商:2

48-2*13=22,22-13>0,22-2*13<0 商:1

商:4+2+1=7 余数:9

 

//整数除法and取模,返回商和余数 pair<int,int> integer_div_3(unsigned int dividend, unsigned int divisor) { if(divisor == 0) { cout<<“非法参数,除零错”<<endl; exit(1); } if(dividend < divisor) return make_pair(0, dividend); unsigned int k, c, quotient=0, remainder; while(dividend > divisor) { %被除数2倍增长 for(k=0,c=divisor;dividend>=c;c<<=1,k++) { if(dividend-c < divisor) { quotient += 1<<k; remainder = dividend-c; break; } } if(dividend-c < divisor) break; quotient += 1<<(k-1); dividend -= c>>1; } return make_pair(quotient, remainder); }

 

if和三目运算符替换

利用逗号表达式和位运算,其中B和C需要有返回值

if(A) B;
else C;

A?B:C;

A && (B,1) || C

 

 

点赞