位运算:二进制中1的个数
2016-03-05 16:32
369 查看
题目:请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1。因此输出2.
1.可能引起死循环的解法:
一个基本思路:先判断整数二进制表示中最右边一位是不是1。接着把输入的整数右移一位,此时原来处于从右边数起的第二位被移到最右边了,再判断是不是1。这样每次移动1位,直到整个整数变成0为止。判断最右边是不是1,只要把整数和1做位与运算看结果是不是0就直到了。1除了最右边一位之外所有位都是0.如果一个整数与1做与运算的结果是1,表示该整数最右边一位是1,否则是0. 代码如下:
但是当输入一个负数时,移位后,最高位仍然为1,如果一直做右移运算,这个数字会变成0xffffffff, 进入死循环。
2.常规解法
为了避免死循环,我们可以不右移输入的数字n. 首先把n和1做与运算,判断n的最低位是不是1.接着把1左移一位得到2,再和n做与运算,判断n的次低位是不是1…这样反复左移,每次都能判断n的其中一位是不是1.基于这种思路,代码如下:
循环次数等于整数二进制的位数。
3.惊喜解法
思路: 如果把一个整数减去1,再和 原整数做与运算,会把该整数最右边一个1变成0.如二进制1100,减去1后变为1011,1100和1011做位与运算是1000.把1100最右边的1变成了0
那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。代码如下:
思路解决
1.可能引起死循环的解法:
一个基本思路:先判断整数二进制表示中最右边一位是不是1。接着把输入的整数右移一位,此时原来处于从右边数起的第二位被移到最右边了,再判断是不是1。这样每次移动1位,直到整个整数变成0为止。判断最右边是不是1,只要把整数和1做位与运算看结果是不是0就直到了。1除了最右边一位之外所有位都是0.如果一个整数与1做与运算的结果是1,表示该整数最右边一位是1,否则是0. 代码如下:
public static int numberOfOne1(int num){ int count = 0; int rs=0; while(num!=0){ if((rs =num & 1)!=0) count++; num = num >> 1; } return count; }
但是当输入一个负数时,移位后,最高位仍然为1,如果一直做右移运算,这个数字会变成0xffffffff, 进入死循环。
2.常规解法
为了避免死循环,我们可以不右移输入的数字n. 首先把n和1做与运算,判断n的最低位是不是1.接着把1左移一位得到2,再和n做与运算,判断n的次低位是不是1…这样反复左移,每次都能判断n的其中一位是不是1.基于这种思路,代码如下:
public static int numberOfOne2(int num){ int count1 = 0; int flag = 1; int rs = 0; int count2 = 0; while(count2<Integer.SIZE){ if((rs=num&flag)!=0) count1++; flag = flag << 1; count2++; } return count1; }
循环次数等于整数二进制的位数。
3.惊喜解法
思路: 如果把一个整数减去1,再和 原整数做与运算,会把该整数最右边一个1变成0.如二进制1100,减去1后变为1011,1100和1011做位与运算是1000.把1100最右边的1变成了0
那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。代码如下:
public static int numberOfOne3(int num){ int count = 0; while(num!=0){ num = (num-1) & num; count++; } return count; }
判断一个整数是不是2的整数次方。一个整数如果是2的整数次方,那么它的二进制表示中有且只有一位是1, 而其他所有位是0.把这个整数减去1之后再和它自己做与运算,这个整数中唯一的1就会变成0. public static boolean is2pow(int num){ return (num & (num-1))==0; } 输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到n.比如10的二进制表示为1010,13的 二进制表示为1101,需要改变1010中的3位才能得到1101. 分两步解决:第一步求这两个数的异或,第二步统计 异或结果中1的个数 public static int diff(int num1, int num2){ int num = num1 ^ num2; int count = numberOfOne3(num); return count; } 把一个整数减去1之后再和原来的整数做位与运算,得到的结果相当于是把整数的二进制表示中的最右边一个1变成0.很多二进制的为题都可以用这个
思路解决
相关文章推荐
- JavaScript常用代码(不定时更新)
- 网络-NSURLSession应用和原理
- 字符串匹配
- Android面试题搜集
- LeetCode : String to Integer (atoi) [java]
- 关于enum与typedef enum的用法小结
- LeetCode题解--2-Add Two Numbers
- 37. Sudoku Solver *HARD*
- 由SequenceFile.Writer(key,value)谈toString()方法
- 笔记:继承设计的技巧
- C#连接数据库代码(基础)
- NSRULConnection网络应用
- EF(EntityFramework) 的 CodeFirst 使用指南二(基本使用)
- HBase -ROOT-和.META.表结构(region定位原理)
- php编写的抽奖程序中奖概率算法
- 解决Chrome插件安装时出现的“程序包无效”问题
- Mac安装Myeclipse2015开发环境
- string类的实现
- PHP strstr()函数详解
- JS操作cookie