计算int 型数值在内存中二进制1的个数

今天在华为OJ上遇到这么一个题目,很简单,但是却总是得不到最好的成绩记录。因此比较了自己的程序、思路与别人的异同,发现还是有很大区别的,遂记录如下。

题目——

输入一个int型整数,求该整数的二进制在内存中有多少个1。例如输入10,由于其二进制表示为1010,有两个1,因此输出2。

思路1

<span style="font-size:18px;">public static void main(String[] args)      {  

         Scanner scanner = new Scanner(System.in);
        int m = scanner.nextInt();
        int num = 0;
        while(m>0){
        	m&=(m-1);
        	num++;
        }

     }  </span><span style="font-size: 16pt;">
</span>

这是最常规的思路。直接利用移位去算,始终判断最后一位是不是1,然后计数。这也是我一开始所所想到的,但是,这种写法只得到了60分。

思路2

<span style="font-size:18px;">private static int count_ones(int a)     {
    	    a = (a & 0x55555555) + ((a >> 1) & 0x55555555);
    	    a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
    	    a = (a & 0x0f0f0f0f) + ((a >> 4) & 0x0f0f0f0f);
    	    a = (a & 0x00ff00ff) + ((a >> 8) & 0x00ff00ff);
    	    a = (a & 0x0000ffff) + ((a >> 16) & 0x0000ffff);

    	    return a;
    	}</span><span style="font-size: 16pt;">
</span>

这是我看别人拿了满分的答案。这种思路比较难想到。一开始我怎么都想不明白他是怎么想出来的。直到翻看书籍,碰巧在《编程之美》上有记载这个题目,并且给出了五种解法。其中有两种就是以上两种。

这道题的本质相当于求二进制数的 Hamming 权重,或者说是该二进制数与 0 的 Hamming 距离,这两个概念在信息论和编码理论中是相当有名的。在二进制的情况下,它们也经常被叫做 population count 或者 popcount 问题,比如 gcc 中就提供了一个内建函数:int __builtin_popcount (unsigned int x)   输出整型数二进制中 1 的个数。但是 GCC 的 __builtin_popcount
的实现主要是基于查表法做的,跟编程之美中解法 5 是一样的。Wikipedia 上的解法是基于分治法来做的,构造非常巧妙,通过有限次简单地算术运算就能求得结果,特别适合那些受存储空间限制的算法中使用。

此外,在这个博客里也有对编程之美里五种解法的详细分析,值得一读。http://blog.csdn.net/shijiemazhenda/article/details/6785674

计算int 型数值在内存中二进制1的个数

时间: 2024-10-08 09:47:52

计算int 型数值在内存中二进制1的个数的相关文章

[NewCoder]求int型正整数在内存中存储时1的个数

输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数. 输入描述: 输入一个整数(int类型) 输出描述: 这个数转换成2进制后,输出1的个数  输入例子:5  输出例子:2 import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int num = 0; S

求int型数据在内存中存储时1的个数

1.求int型数据在内存中存储时1的个数 输入一个int型数据,计算出该int型数据在内存中存储时1的个数. 我们非常easy想到例如以下方法: #include <iostream> using namespace std; int main() { int n,cnt=0; cin>>n; while(n) { if(n%2==1) cnt++; n=n/2; } cout<<cnt<<endl; return 0; } 在对代码进行測试时输入负数无法得

(一)求 int 型数据在内存中存储时 1 的个数

题目:求 int 型数据在内存中存储时 1 的个数 描述:输入一个 int 型数据,计算出该 int 型数据在内存中存储时 1 的个数 运行时间限制: 10 sec 内存限制:128 MByte 输入:输入一个整数(int 类型) 输出:这个数转换成2进制后,输出 1 的个数 1 #include <stdio.h> 2 3 int GetCount(int num) 4 { 5 /* 功能实现 */ 6 int ret = 0; 7 8 while (num) 9 { 10 num &

c语言char型常量在内存中是以什么形式存放的

char型常量(字符),在计算机中是按其ASCII值进行存储,ASCII是"整型类"数据,在内存中全部以补码形式进行存放. 补码是一种二进制数据表示形式.整数分为正数.负数和零,计算机设计初期,规定,以字节的最高位表示符号,其余位表示数值,来表示有符号数据,这就是原码.但原码表示法中出现了"正0"和"负0"的表示现象,因此,又研究出来了补码概念,最终用补码来进行数据的存储. 规定: 正数的原码与补码相同. 负数的补码=反码+1, 反码是原码符号位

求整型中二进制1的个数

1. 确定二进制1的个数: ->循环死& ->x-1&x ->查表,分写死与动态生成,动态生成方法:BitsSetTable256[i] = (i &1) + BitsSetTable256[i /2]; ->并行位运算: int BitCount4(unsigned int n) {    n = (n &0x55555555) + ((n >>1) &0x55555555) ;    n = (n &0x3333333

求一个整数中二进制1的个数

题目:求一个整数二进制表示1的个数 第一版: 思路:如果一个整数与1做与运算,结果为1,那么该整数最右边一位是1,否则是0: int NumberOf1(int n) { int count = 0; while (n) { if (n&1)//如果一个整数与1做与运算的结果是1,表示该整数最右边是1,否则是0: { count++; } n = n>>1; } return count; } 缺点:因为代码当中有右移,当是负数的时候,要考虑符号位:如果一个正数,右移之后在最左边补n个

获取内存中整数二进制形式

采用移位和相与方式求整数在内存中的二进制形式. #include<stdio.h> typedef int DataType; int num_covert_binary(DataType num); void main() { DataType num; num = -1; num_covert_binary(num); num = 12; num_covert_binary(num); getchar();//让console 等待一下 } int num_covert_binary(Da

《斯坦福大学:编程范式》第二节:基本数据类型在内存中的二进制表达

我们以C/C++为例. 基本数据类型有: bool        1 byte char 1 byte       256个字符,其中75个字符是常用的   short 2bytes int 4bytes long 4bytes float 4 bytes double 8 bytes ---------------------------bytes------------------------------------- 1 bytes(字节) = 8 bit(位 binary digit)

简单了解:在内存中的数据

内存原理 开启电源,启动BIOS,CPU工作,调用内存,内存跟硬盘索要资源 当你点击一个文件的时候数据经过数据总线传达到CPU,CPU发送指令到内存,内存那里会跟硬盘沟通,问他有没有这个东西,他说有,你就会看到这个文件夹里面是什么东西. (Xee:RAM 是随机存取存储器,它的特点是易挥发性,即掉电失.--妈蛋,难怪一断电,我的东西没保存,就找不到了-- 既然内存是用来存放当前正在使用的(即执行中)的数据和程序,那么它是怎么工作的呢?我们平常所提到的计算机的内存指的是动态内存(即DRAM),动态