求二进制数中"1"的个数
来源:互联网 发布:里程 积分 知乎 编辑:程序博客网 时间:2024/06/06 01:00
本题同样来自《编程之美》。
对于一个字节(8bit)的无符号整型变量,求其二进制表示中“1”的个数。
笨方法:
对于二进制操作,除以一个2,原来的数字就会减少一个0.(可以类比十进制,十进制除以一个10,则相应会减少一个0)
如果除的过程中有余,那么就表示当前位置有一个1.
#include<stdio.h>typedef unsigned char BYTE;int Count(BYTE v){int num = 0;while(v){if(v%2==1)num++;v=v/2;}return num;}int main(){BYTE b1 = 0;BYTE b2 = 129;BYTE b3 = 255;printf("b1 :%d\n",Count(b1));printf("b2 :%d\n",Count(b2));printf("b3 :%d\n",Count(b3));return 0;}
好方法:
右移操作同样可以达到相除的目的。
右移后,与00000001进行“与”操作。
int Count(BYTE v){int num = 0;while(v){num+=v&0x01;v>>=1;}return num;}
聪明方法:
虽然使用位操作的效率比笨方法高多了,但是,时间复杂度仍为O((log2)v)。
想办法使时间复杂度只与“1”的个数相关。
若v为:01000000,则v-1为:00111111。两者相与为0。
若v为:01100000,则v-1为:01011111。两者相与为01000000。此时和第一种情况一样。再次操作后,为0。
所以,根据这个规律,我们考虑v和v-1相与,统计结果为0之前的次数即为“1”的个数。
int Count(BYTE v){int num = 0;while(v){v&=(v-1);num++;}return num;}
此外,还有空间换时间的方法。
将所有的256种情况存储在数组中。
根据v的不同,直接取相应的情况即可。
算法时间复杂度仅为O(1)。
0 0
- 求二进制数中1的个数
- 求二进制数中1的个数
- 求二进制数中1的个数
- 求二进制数中1的个数
- 求二进制数中1的个数
- 求二进制数中1的个数
- 求二进制数中1的个数
- 求二进制数中1的个数
- 求二进制数中 1 的个数
- 求二进制数中1的个数
- 求二进制数中1的个数
- 求二进制数中1的个数
- 求二进制数中1的个数
- 求二进制数中1的个数
- 求二进制数中1的个数
- “求二进制数中1的个数”
- 求二进制数中1的个数
- 求二进制数中1的个数
- hightchart 报表
- mysql数据库索引误区
- 浅谈localhost
- ImageButton如何用
- Spring 入门案例(含IOC、AOP、SpringMVC、Spring JDBC)
- 求二进制数中"1"的个数
- LCS
- 浅谈MVP实现Android应用层开发
- bcm68380 complile env building
- EditText的字体加粗
- 兼容CommonJS规范,AMD规范,CMD规范的JS写法
- libelf 介绍
- HDOJ1305 Immediate Decodability
- 如何用 RapidMiner 6.4 进行中文分词