package BitCount;
/**
* 任意给定一个32位无符号整数n,求n的二进制表示中1的个数,比如n = 5(0101)时,返回2,n = 15(1111)时,返回4
*
* @author vivizhyy
*
*/
public interface BitCountMethods {
/** 移位+计数 */
public int normal(int x);
/** 不断清除x的二进制表示中最右边的1,同时累加计数器,直至x为0 */
public int quick(int x);
/**
* @see #static8bit(int)
*/
public int static4bit(int x);
/**
* 首先构造一个包含256个元素的表table,table[i]即i中1的个数,这里的i是[0-255]之间任意一个值。
* 然后对于任意一个32bit无符号整数n
* ,我们将其拆分成四个8bit,然后分别求出每个8bit中1的个数,再累加求和即可,这里用移位的方法,每次右移8位
* ,并与0xff相与,取得最低位的8bit
* ,累加后继续移位,如此往复,直到n为0。所以对于任意一个32位整数,需要查表4次。以十进制数2882400018为例
* ,其对应的二进制数为10101011110011011110111100010010
* ,对应的四次查表过程如下:红色表示当前8bit,绿色表示右移后高位补零。
*
* 第一次(n & 0xff) 10101011110011011110111100010010
*
* 第二次((n >> 8) & 0xff) 00000000101010111100110111101111
*
* 第三次((n >> 16) & 0xff)00000000000000001010101111001101
*
* 第四次((n >> 24) & 0xff)00000000000000000000000010101011
*/
public int static8bit(int x);
/** 先将n写成二进制形式,然后相邻位相加,重复这个过程,直到只剩下一位。
* 1 1 0 1 1 0 0 1
* \ / \ / \ / \ /
* 2 1 1 1
* \ / \ /
* 3 2
* \ /
* 5
*/
public int parallel(int x);
/** http://www.cnblogs.com/graphics/archive/2010/06/21/1752421.html */
public int perfectness(int x);
}
package BitCount;
public class BitCounts implements BitCountMethods {
@Override
public int normal(int x) {
int c = 0;
for (; x > 0; x >>>= 1) {
c += x & 1; // 如果当前位是 1,计数器加 1
}
return c;
}
@Override
public int quick(int x) {
int c = 0;
for (; x > 0; c++) {
x &= (x - 1); // 清除最右边的 1
}
return c;
}
@Override
public int static4bit(int x) {
int[] table = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
int c = 0;
for (; x > 0; x >>>= 4) {
c += table[x & 0xF];
}
return c;
}
@Override
public int static8bit(int x) {
int[] table = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2,
2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3,
4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5,
4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2,
3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4,
4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5,
6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3,
4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5,
5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5,
4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5,
6, 6, 7, 6, 7, 7, 8, };
int c = 0;
for(; x > 0; x >>>= 8){
c += table[x & 0xFF];
}
return c;
}
@Override
public int parallel(int x) {
// 0x55 = 0101 0101
x = (x & 0x55555555) + ((x >>> 1) & 0x55555555);
//0x33 = 0011 0011
x = (x & 0x33333333) + ((x >>> 2) & 0x33333333);
//0x0f = 0000 1111
x = (x & 0x0f0f0f0f) + ((x >>> 4) & 0x0f0f0f0f);
//0x00ff = 0000 0000 1111 1111
x = (x & 0x00ff00ff) + ((x >>> 8) & 0x00ff00ff);
//0x0000ffff = 0000 0000 0000 0000 1111 1111 1111 1111
x = (x & 0x0000ffff) + ((x >>> 16) & 0x0000ffff);
return x;
}
@Override
public int perfectness(int x) {
int temp = x - (x >>> 1) & 033333333333 - (x >>> 2) & 011111111111;
return (temp +(temp >>>3)) & 030707070707 % 63;
}
}
package BitCount;
import static org.junit.Assert.*;
import org.junit.Test;
public class BitCountMethodsTest {
BitCountMethods bcm = new BitCounts();
int x = 123;
@Test
public final void testNormal() {
assert(bcm.normal(x) == 6);
}
@Test
public final void testQuick() {
assert(bcm.quick(x) == 6);
}
@Test
public final void testStatic4bit() {
assert(bcm.static4bit(x) == 6);
}
@Test
public final void testStatic8bit() {
assert(bcm.static8bit(x) == 6);
}
@Test
public final void testParallel() {
assert(bcm.parallel(x) == 6);
}
@Test
public final void testPerfectness() {
assert(bcm.perfectness(x) == 6);
}
}
分享到:
相关推荐
统计整数的二进制表示形式中有几个1(java实现),代码中有三种方法,分别是利用除、余的方法,位运算,以及利用“与”运算的方法。其中第三种方法效率最高,二进制数中有几个1,算法中的循环内的运算就执行几次。
801. 二进制中1的个数算法:#位运算每次减去给定整数 x 二进制中的最后一位 1(lowbit(n) = n & -n),一共能减几次 x 二进制中就有几个
主要介绍了Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting),本文直接给出实现代码,代码中包含详细注释,需要的朋友可以参考下
11、二进制中1的个数 12、数值的整数次方 13、调整数组顺序使奇数位于偶数前面 14、链表倒数第k个节点 15、反转链表 16、合并两个排序列表 17、树的子结构 18、二叉树的镜像 19、顺时针打印矩阵 20、包含min函数的栈...
leetcode题库 Leetcode 算法总结 (Java版) 题库来源: 每日一题【综合】(One question per day) 栈(stack_items) ... 二进制中1的个数(The_number_of_1s_in_binary.java) 主要元素(Main_element.ja
sword-for-offer 使用Python3用pythonic的方式实现《剑指Offer 第...15 二进制中1的个数 第3章 高质量的代码 3.3 代码的完整性 16 数值的整数次方 17 打印从1到最大的n位数 18 删除链表中的节点 19 正则表达式 20 表示
进制转换.py,两种排序方法.py,买苹果.py,美团.py,末尾0的个数.py,求和.py,求和-好未来.py,删除公共字符.py,输入n个整数,输出出现次数大于等于数组长度一半的数。.py,数列还原.py,数字翻转.py,数字和为sum的方法数....
二进制中1的个数 面试题16 数值的整数次方 面试题17 打印从1到最大的n位数 面试题18 删除链表的节点 面试题19 正则表达式匹配 面试题20 表示数值的字符串 面试题21 调整数组顺序使奇数位于偶数前面 面试题22 链表中...
二进制中1的个数 数值的整数次方: 调整数组顺序,使奇数位于偶数前面: 链表中倒数第k个节点: 反转链表: 合并两个排序的链表 树的子结构 二叉树的镜像 顺时针打印矩阵 包含main函数的栈 栈的压入、弹出序列 从上往下...
二、循环实现 Java /* * 8皇后问题: * * 问题描述: * 在一个8×8的棋盘里放置8个皇后,要求每个皇后两两之间不相冲突 *(在每一横列,竖列,斜列只有一个皇后)。 * * 数据表示: * 用一...
1 逻辑类问题(A类)-指设计、编码中出现的计算正确性和一致性、程序逻辑控制等方面出现的问题,在系统中起关键作用,将导致软件死机、功能正常实现等严重问题; 接口类问题(B类)-指设计、编码中出现的函数和...
二进制数据类型 row 1~2000字节 可变长二进制数据,在具体定义字段的时候必须指明最大长度n long raw 1~2GB 可变长二进制数据 LOB数据类型 clob 1~4GB 只能存储字符数据 nclob 1~4GB 保存本地语言字符集数据 blob...