计算一个二进制数中1的个数

如果我们要计算一个二进制数中1的个数,很显然会想到运用位运算的知识来解决。

前面有篇博文,讲如何判断一个数是否是2的幂,其实就是判断一个二进制数中是否仅含有一个1,解法是x & x - 1

在理解上式的前提下,我们可以发现,如果二进制数x中包含不止一个1,那么x&x-1的结果就使得原先的x失去的最末尾了一个1。

因此,我们可以利用x&x-1循环得到x中1的个数。

代码如下:

 1 int
 2 CountOnes(int num)
 3 {
 4     int count;
 5     for (count = 0; num != 0; count++) {
 6         num &= num - 1;
 7     }
 8
 9     return count;
10 }

或许还有一种思路:如果一个数x的最后一位含有1,则该数是奇数,因此我们可以一步一步将x右移,判断x是否为奇数,如果是,则当前的最末位是1。直到x为零为止。考虑到x是负数的话,可能会导致算术右移(右移的时候,最高位补1),导致1的个数是无穷多。我们将函数的参数设为无符号整数unsigned int。

代码如下:

 1 int
 2 CountOnes(unsigned int num)
 3 {
 4     int count;
 5     for (count = 0; num != 0; num >>= 1) {
 6         if (num % 2 == 1) {
 7             count++;
 8         }
 9     }
10     return count;
11 }

另外,二进制数中1的个数在计算机科学上称之为Hamming weight,已经有许多实现它的高效的方法,并且许多的处理器在机器指令的层面支持对它的计算,GCC也从编译器的层面提供了内置的函数对其进行运算(我还没有测试)。详见Hamming weight

时间: 2024-08-02 00:43:44

计算一个二进制数中1的个数的相关文章

用c语言实现 计算一个字符串中单词的个数

#include<stdio.h> int main() { char string[100]; int i , num=0 ,word=0; char c; gets(string);//从键盘得到一个字符串 for(i=0;(c=string[i])!='\0';i++)//字符不是'\0'就执行循环 { if(c==' ')//遇到空格word置0 { word=0; } else if(word==0)//未遇到空格且word为0则num加一且word置1 { word=1; num+

计算一个字符串中每个字符出现的个数

需求:计算一个字符串中每个字符出现的次数 分析: 使用Scanner获取用户输入的字符串 创建Map集合,Key是字符串中的字符,value是字符的个数 遍历字符串,获取每一个字符 使用获取的字符,去Map集合判断key是否存在 key存在:通过字符(key),获取value(字符个数)value++ put(key,value )把新的value存储到Map集合中 key不存在:put(key,1) 遍历Map集合,输出结果 package day13; import java.util.Ha

[华为机试练习题]45.求某二进制数中1的个数

题目 描述: 题目标题: 求某二进制数中1的个数. 给定一个unsigned int型的正整数,求其二进制表示中"1"的个数,要求算法的执行效率尽可能地高. 详细描述: 原型: int GetCount(unsigned int num) 输入参数: num 给定的正整数 输出参数(指针指向的内存区域保证有效): 无 返回值: 返回1的个数 举例: 输入13,则对应的二进制是1101,那么1的个数为3个.则:返回3. 练习阶段: 初级 代码 /*--------------------

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

求二进制数中1的个数 继京东618店庆时买的<编程之美>这本书,翻了翻,发现里面的题还是挺有意思的,看起来我们觉得很简单的题目,解法却有很多很多种,真是一个比一个巧妙,于是,决定记录一下. 书中的题目如下 对于一个字节(8bit)的无符号数,求其二进制表示中"1"的个数,要求算法的执行效率尽可能高. 就像书中给我们说的一样,我们一般人可能想到的解决方法如下 int countOne(int n){ int count=0; while(n){ if(n%2==1){ cou

编程之美-02数字之魅-求二进制数中1的个数

题目:求二进制数中 1 的个数 对于一个字节(8bit)的无符号整型变量,求其二进制表示中"1"的个数,要求算法的执行效率尽可能地高. 解法一:移位->判断->累计 解法二:除2->判断->累计 解法三:v &= (v -1)需要掌握 ? 2 3 4 5 6 7 8 int num = 0; while(v) {     v &= (v -1);     num++; } return num; ? 2   解法四:分支操作(swicth-cas

求二进制数中1的个数——引发的问题

<编程之美>书中有这样的一道问题“求二进制数中1的个数” 题目:对于一个字节(8bit)的无符号整形变量,求其二进制中“1”的个数,要求算法的执行效率尽可能高. 我使用java语言处理:输出结果是3 public class Count { public static int Count(byte d){ int num = 0; while (d != 0) { d &= (d-1);//比较1的个数 num++; } return num; } public static void

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

解法一:若二进制末尾为1,则除以2余1: int count(int a) { int num=0; while(a) { if(a%2==1) ++num; a=a/2; } return num; } 解法二:使用移位操作相除: int count(int a) { int num=0; while(a) { num+=a&0x01; a>>=1; } return num; } 解法三:以上两种算法复杂度log2(t),t为a的二进制表示位数,若要求复杂度仅与二进制表示中1的个数

字符串之“统计一个字符串中单词的个数”

题目:统计一个字符串中单词的个数 输入一行字符,统计其中有多少个单词,单词之间用空格分隔开 输入:my name is jacky 输出:the number of word is 4 代码如下: #include <stdio.h> int main(int argc, char *argv[]) { char str[80]; int i=0,num=0,flag=0; char c; gets(str); while((c=str[i])!='\0') { if(c==' ') flag

判欧拉回路或求一个图中欧拉图的个数

判欧拉图两个条件首先联通,其次度全部为欧度.那么就很easy了. 题目:hdoj1878 求一个图中欧拉图的个数. 首先通过连通性求出各个子图,然后求子图中奇数度的个数cnt,cnt/2为欧拉图的个数.若子图没有奇数度,则为一个欧拉回路. 题目:hdoj3018Ant Trip 注意这个题目中可能出现孤立点,不算入欧拉图中. AC代码: include include include include include include include include include include