二进制中1的个数以及时间比较

public class Algorithm {

	public static void main(String[] args) {
		long t1 = System.currentTimeMillis();
		for (int i = -10000000; i < 10000000; i++) {
			countOne(i);
		}
		long t2 = System.currentTimeMillis();
		long p1 = t2 - t1;

		long t3 = System.currentTimeMillis();
		for (int i = -10000000; i < 10000000; i++) {
			countOne2(i);
		}
		long t4 = System.currentTimeMillis();
		long p2 = t4 - t3;
		System.out.println(p1 + "----" + p2);
	}

	/**
	 * 位运算求1的个数
	 *
	 * @param x
	 * @return
	 */
	public static int countOne(int x) {
		x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
		x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
		x = (x & 0x0f0f0f0f) + ((x >> 4) & 0x0f0f0f0f);
		x = (x & 0x00ff00ff) + ((x >> 8) & 0x00ff00ff);// (1)
		x = (x & 0x0000ffff) + ((x >> 16) & 0x0000ffff);// (2)
		// x = (x * 0x01010101) >> 24;(3)
		return x;
	}

	/**
	 * 1的个数
	 *
	 * @param x
	 * @return
	 */
	public static int countOne2(int x) {
		int cnt = 0;
		while (x != 0) {
			x &= (x - 1);
			cnt++;
		}
		return cnt;
	}
}

结果:

位运算的时间有波动,非位运算的耗时基本上在250-270左右。位运算的速度确实快。

其中(1)和(2)的效果与(3)相同

时间: 2024-10-11 18:18:42

二进制中1的个数以及时间比较的相关文章

第2章 数字之魅——求二进制中1的个数

求二进制中1的个数 问题描述 对于一个字节(8bit)的变量,求其二进制表示中“1”的个数,要求算法的执行效率尽可能地高. [解法一] 可以举一个八位的二进制例子来进行分析.对于二进制操作,我们知道,除以一个2,原来的数字将会减少一个0.如果除的过程中有余,那么就表示当前位置有一个1. 以10 100 010为例: 第一次除以2时,商为1 010 001,余为0. 第二次除以2时,商为101 000,余为1. 因此,可以考虑利用整型数据除法的特点,通过相除和判断余数的值来进行分析.于是有了如下的

Algorithm --&gt; 二进制中1的个数

行文脉络 解法一——除法 解法二——移位 解法三——高效移位 解法四——查表 扩展问题——异或后转化为该问题 对于一个字节(8bit)的变量,求其二进制“1”的个数.例如6(二进制0000 0110)“1”的个数为2,要求算法效率尽量高. 解法一 对于二进制数来说,除一个2,就少一位,可以判断这个少的位来确定“1”的个数. 例如:6(0000 0110) 0000 0110 / 2 = 0000 0011     ----少的一位为0 0000 0011 / 2 = 0000 0001    

编程之美2.1 求二进制中1的个数

最近一段的时间,一直在看编程之美之类的算法书籍,刚开始看编程之美,感觉到难度太大,有时候也不愿意去翻动这本书,不过,经过一段时间的修炼,我也彻底的喜欢上这本书了, 书中的算法涉及到很多方面,树,链表,位运算,数组,hash表应用等等. 由于最近事情也忙得差不多了,我重新写了一遍编程之美中的算法,在这里记录下来,以便以后阅读方便. 第一道题从2.1写起,这道题目难度不是很大,首先,给出这个题目的函数声明: /*2.1 求二进制中1的个数*/ int DutCountOf1InBin_1(unsig

[剑指Offer]12.二进制中1的个数

题目 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路 把一个整数减去1,再和原整数做与运算,会把整数最右边一个1变成0.那么一个整数的二进制表示中有多少个1,就可以进行多次这样的操作. 代码 /*--------------------------------------- * 日期:2015-07-20 * 作者:SJF0115 * 题目: 12.二进制中1的个数 * 结果:AC * 网址:http://www.nowcoder.com/books/coding-int

二进制中1的个数

题目描述: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 输入: 输入可能包含多个测试样例. 对于每个输入文件,第一行输入一个整数T,代表测试样例的数量.对于每个测试样例输入为一个整数. .n保证是int范围内的一个整数. 输出: 对应每个测试案例, 输出一个整数,代表输入的那个数中1的个数. 样例输入: 3 4 5 -1 样例输出: 1 2 32 /* 二进制中1的个数 by Rowandjj 2014/7/24 */ #include<stdio.h> #include

【剑指offer】二进制中1的个数

题目描述: 请实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如把9表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2. 分析描述: 1.对一个整数的二进制形式,要想知道其中1的个数,首先想到的应该就是遍历整个二进制数,用到的方法当然就是移动了(包含左移或右移).例如,用1来跟给定的整数做与运算.如果结果为1,则证明整数的二进制形式中,最右边的一位是1,如果结果是0,则证明整数的二进制形式中,最右边的一位是0. int NumberOf1(int n) { int co

nyoj 数的二进制中1的个数

很有用O(n)内实现三类数字分离,以前大多是分成两类数据,快排中分成两类,还有就是"ab***vvvc" 在O(n)中变成 abvvc****,变成两类划分问题 #include<iostream> #include<string.h> using namespace std; const int N=1000; char c[N]; int len; void swap(char &a,char &b) { //a=a^b; //b=a^b;

计算二进制中1的个数

问题:计算某个数的二进制中1的个数 思路:x = x & (x-1) 将 x 的二进制最右面的一个 1 变为 0,其余保持不变.反复操作,直到变为 0 为止,计算操作次数,即为 x 的二进制中 1 的个数. 证明:假设 x 的二进制末尾为 10...0 [末尾有 k 个 0,k = 0,1,2,...]. 则 x - 1 的二进制末尾 k+1 位为 01...1 [末尾有 k 个 1,k = 0,1,2,...],其他与 x 相同. 从而 x & (x-1) 的末尾 k+1 位为 00..

二进制中1的个数(2)

规律总结: 把一个整数减去1之后再和原来的整数做位与运算,得到的结果相当于是把整数的二进制表示中最右边的一个1变为0. 题目1: 用一条语句判断一个整数是不是2的整数次方. 解决思路: 如果一个整数是2的整数次方,那么二进制表示中只有一位是1.将这个数减去1之后再与本身,结果为0则表示这个整数位2的整数次方. bool func(int n) { return ((n-1)&n)==0; } 题目2: 输入两个整数m,n.计算需要改变m的二进制表示中的多少位才能得到n. 思路: 先将m异或n,结