剑指offer笔试面试题之——位运算

来源:互联网 发布:菜鸟网络工资 编辑:程序博客网 时间:2024/04/28 21:55

位运算

位运算是把数字用二进制表示之后,对每一位上0或者1的运算。

位运算总共只有五种运算:与、或、异或、左移和右移,运算规律总结如下:

与(&):     0&0 = 0;   1&0 = 0;     0&1 = 0;     1&1 = 1.

或(|):     0|0 = 0;   1|0 = 1;     0|1 = 1;     1|1 = 1.

异或(^):   0^0 = 0;   1^0 = 1;     0^1 = 1;     1^1 = 0.

左移运算符m << n表示把m左移n位。左移的时候,最左边的n为将被丢弃,同时在最右边补上n个0。比如:00001010<<2 = 00101000,00001010<<3 = 01010000。

右移运算符m << n表示把m右移n位。左移的时候,最左边的n为将被丢弃。但右移时有两种情况:第一,数字是一个无符号数值,则用0填补最左边的n位;第二,

数字是一个有符号数值,则用符号数位填充最左边的n位,即若数字原先是正数,则右移之后在最左边补n个0,若数字原先是负数,则右移之后在最左边补n个1。

比如:00001010>>2 = 00000010    10001010>>3 = 11110001


题目:实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位1。因此输入9,该函数输出2。

常规解法:

把n和1做与运算,判断n的最低位是不是为1。接着把1左移一位得到2,再和n做与运算,就能判断n的次低位是不是1……这样反复左移,每次都能判断

n的其中一位是不是。

#include<iostream>using namespace std;int Numberof1(int n){int count = 0;unsigned int flag = 1;while(flag){if(n & flag)count++;flag = flag << 1;}return count;}int main(){int a;cout<<"a = ";cin>>a;Numberof1(a);cout<<a<<" 的二进制中有 "<<Numberof1(a)<<" 个1."<<endl;}

输出:

a = 9
9 的二进制中有 2 个1.
Press any key to continue

给面试官带来惊喜的解法:

把一个整数减去1,都是把该整数最右边的1变成0,如果它的后面还有0 的话,把它后面的所有0都变成1,而把它左边所有位都保持不变。接下来把这个整数和

它减去1的结果做与运算,相当于把它最右边的1变成0。例如:12(1100)减去1位11(1011)。在把1100和1011做与运算,结果得到1000.在把1000减1,得0111,把1000与0111做与运算的0000即此时为0,进行了两次与运算count为2,说明12(1100)中有两个1。

int Numberof2(int n){int count = 0;while(n){++count;n = (n-1)&n;}return count;}int main(){int a;cout<<"a = ";cin>>a;//Numberof1(a);Numberof2(2)//cout<<a<<" 的二进制中有 "<<Numberof1(a)<<" 个1."<<endl;cout<<a<<" 的二进制中有 "<<Numberof2(a)<<" 个1."<<endl;}

相关题目:

1.用一条语句判断一个整数是不是2的整数次方。一个整数如果是2的整数次方,那么它的二进制表示中有且只有一位是1,而其他所有位都是0.(把这个整数减去

1之后再和它自己做与运算,这个整数中唯一的1就会变成0。即只能做一次与运算count = 1)

int Numberof(int n){int count = 0;while(n){++count;n=(n-1)&n;}if(count =1)return true;}int main(){int n;cout<<"整数n是否为2的整数次方"<<"n = ";cin>>n;Numberof(n);cout<<"count = "<<Numberof(n)<<" 整数n是2的整数次方。"<<endl;}

2.输入两个整数m, n计算需要改变m的二进制表示中的多少位才能达到n。比如:10的二进制1010,13的二进制1101,需要改变1010中的3位才能得到1101,。

(分为两步:第一,求这两个数的异或;第二,统计异或结果中1的位数,1的位数即为需要改变的位数。)

int Numberof3(int m, int n){int count = 0;int a = m^n;while(a){++count;a = (a-1)&a;}return count;}int main(){int b,c;cin>>b>>c;Numberof(b,c);cout<<Numberof(b,c)<<endl;}

3.实现对一个8bit数据(unsigned char类型)的指定位(例如第n位)置0或者置1操作,并保持其他地位不变。

函数原型:void set_bit(unsigned char *p_data, unsigned char position, bool flag)

函数参数说明:

P_data是指定的源数据,position 是指定位(其值范围1~8);flag表示是置0还是1操作,true:置1,flase:置0.

#include<stdio.h>void bit_set(unsigned char *p_data,unsigned char position,int flag) {     unsigned char a=1;     a=a<<(position-1);     if(flag==1) {        *p_data=*p_data|a; }     if(flag==0) {         a=~a;         *p_data=*p_data&a; } } int main(){unsigned char c = 10 ;bit_set(&c, 3, 1);printf("%d\n",c);return 0;}





阅读全文
0 0
原创粉丝点击