文档章节

统计整数二进制表示中1的个数

一贱书生
 一贱书生
发布于 2016/11/18 15:20
字数 592
阅读 3
收藏 0

解决这个问题第一想法肯定是一位一位的去判断,是1计数器+1,否则不操作,跳到下一位,十分容易,编程初学者就可以做得到!

 

于是很容易得到这样的程序:

 

int Sum1ByBin(int num)
{
	int sum = 0;
	while (num)
	{
		if(sum %2 ==1)
		{
			sum ++;
		}
		sum/=2;
	}
	return sum;
}


 

 


或者用牛逼的位运算:

 

int Sum1ByBin(int num)
{
	int sum = 0;
	while (num)
	{
		sum += num&1;
		num>>1;
	}
	return sum;
}

 

 

上面这两篇代码是用的同样的算法, 时间复杂度是二进制的位数,于是可以想一下,有没有只有与二进制中1的位数相关的算法呢?

可以考虑每次找到从最低位开始遇到的第一个1,计数器加1然后把它清零,然后继续找下一个1。方法就是n&(n-1),这个操作对比当前位高的位没有任何影响,

对低位完全清零。举个栗子吧!5。 5是101,第一次运算101&100 == 100,并且计数器加一,第二次运算100&011 == 0,计数器加一。循环结束啦!

所以5有2个1。牛逼吧! 看看代码是怎么实现的:

 

int Sum1byBin(int num)
{
	int sum = 0;
	while(num)
	{
		num &= num-1;
		sum++;
	}
	return 0;
}

很是简单,这就是位运算的好处,据说这个算法没把位运算发挥到极致,也没有得到这个算法最优解。

 

请读者先look一段代码,看看能不能看懂是什么功能:

 

int Sum1byBin(int num)
{
	num =	(num&0x55555555)	+	((num>>1)&0x55555555);
	num = (num&0x33333333)	+	((num>>2)&0x33333333);
	num	=	(num&0x0f0f0f0f)	+	((num>>4)&&0x0f0f0f0f);
	num	=	(num&0x00ff00ff)	+	((num>>4)&&0x00ff00ff);
	num	=	(num&0x0000ffff)	+	((num>>4)&&0x0000ffff);

	return num;
}

卧槽,这个是在玩什么中的制表符导致空格这么大的不怪我!

 

回想第一次遇到这个代码的时候我第一印象,这是什么**玩意,后来经过分析并且有高手帮助理解,这个功能正是利用了位运算,将一个数中二进制表中1 的个数算了出来。利用的是分治思想,先计算每对相邻的2位中有几个1,再计算相邻的4位有一个1 ,再计算相邻的8位、16位、32位有几个1,到此结束,32位的机器int就是32位,所以算

到32位就够啦!!!

 

 

 

© 著作权归作者所有

共有 人打赏支持
一贱书生
粉丝 19
博文 724
码字总数 600123
作品 0
面试算法知识梳理(14) - 数字算法

面试算法代码知识梳理系列 面试算法知识梳理(1) - 排序算法 面试算法知识梳理(2) - 字符串算法第一部分 面试算法知识梳理(3) - 字符串算法第二部分 面试算法知识梳理(4) - 数组第一部分 面试...

泽毛
2017/12/28
0
0
面试精选之位操作问题集锦

Java 中位运算符有与(&)、或(|)、非(~)、异或(^)、左移(<<)、右移(>>)、无符号右移(>>>),只针对 int 类型有效,也可以作用于 byte、short、char、long,当为这四种类型时,J...

JohnnyShieh
2017/12/28
0
0
bitset bitmap 海量数据处理

bitmap:是一个十分有用的结构。所谓的Bit-map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素。由于采用了Bit为单位来存储数据,因此在存储空间方面,可以大大节省。 适用范围...

您这磨人的小妖精
2015/09/05
628
0
C位运算笔记(根据网上内容整理)1

什么是位运算? 程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。由于位运算直接对内存数据进行操作,不需要转成十进制,...

cjs520
06/28
0
0
C位运算笔记(根据网上内容整理)1

什么是位运算? 程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。由于位运算直接对内存数据进行操作,不需要转成十进制,...

cjs520
06/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

原型模式

1、原型模式-定义 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 克隆(浅度克隆->拷贝值类型或者引用,深度克隆->创建新的对象,开辟新的内存) 例如客户端知道抽象Pro...

阿元
今天
57
0
awk命令扩展使用操作

awk 中使用外部shell变量 示例1 [root@centos01 t1022]# A=888[root@centos01 t1022]# echo "" | awk -v GET_A=$A '{print GET_A}'888[root@centos01 t1022]# echo "aaaaaaaaaaaaa" | aw......

野雪球
今天
48
0
深入解析MySQL视图VIEW

Q:什么是视图?视图是干什么用的? A:视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据字典中的。   通过视图,可以展现基表的部分数据;...

IT--小哥
今天
52
0
虚拟机学习之二:垃圾收集器和内存分配策略

1.对象是否可回收 1.1引用计数算法 引用计数算法:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时候计数器值为0的对象就是不可能...

贾峰uk
今天
55
0
smart-doc功能使用介绍

smart-doc从8月份底开始开源发布到目前为止已经迭代了几个版本。在这里非常感谢那些敢于用smart-doc去做尝试并积极提出建议的社区用户。因此决定在本博客中重要说明下smart-doc的功能,包括使...

上官胡闹
昨天
51
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部