OJ题库:统计二进制中1的个数(三种方法)

简介: OJ题库:统计二进制中1的个数(三种方法)

1.方法一:

       用十进制的方法思考,在十进制转二进制的过程中,我们要反复的将目标数字除以2,再对2取模,在对2取模的过程中,其实我们就得到了每一位二进制数(如下图所示),那么咱们一旦得到一位二进制数字,那我们就对其进行一次判断,如果是1,我们就设定一个计数器,并且加一,最后用这个计数器作为返回值,我们就得到了目标数字二进制中1的个数


代码实现及详解

       函数numberof1中的参数之所以用unsigned int是因为这样可以避免负数的输入造成错误的结果,我们讲输入转化成没有符号的数字就可以得到正确的结果了。进入函数后我们使用while循环一直判断n对2取模是否为1(也就是二进制数是否为1),为1计数器就加1,最后n等于0,结束循环,返回计数器作为结果

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int numberof1(unsigned int n)
{
  int count = 0;
  while (n)
  {
    if (n % 2 == 1)
    {
      count++;
      n /= 2;
    }
  }
  return count;
}
int main()
{
  int n = 0;
  scanf("%d", &n);
  int ret = numberof1(n);
  printf("%d的二进制中1的个数为%d\n", n, ret);
  return 0;
}

方法二:

       首先我们知道,int型是4个字节,一个字节是8比特,也就是说一个整数在计算机中是以4*8=32位比特位来存储的,那我们只需要对这32位比特位依次遍历,不就得到了总共二进制的个数了吗。

代码实现及详解

我们使用一个for循环来循环32次,每一次循环我们都将目标数n右移i位,再与上1,我们知道0与1等于0,1与1等于1,1的二进制表示为00000000000000000000000000000001,也就是说任何数n与上1,都只能得到那个数的最后一位二进制数,知道了这些,我们就可以进行判断了,在判断了最后一位数是1后计数器就加1,然后依次遍历,最后得到结果

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int numberof1(int n)
{
  int count = 0;
  for (int i = 0; i < 32; i++)
  {
    if (((n >> i) & 1) == 1)
    {
      count++;
    }
  }
  return count;
}
int main()
{
  int n = 0;
  scanf("%d", &n);
  int ret = numberof1(n);
  printf("%d的二进制中1的个数为%d\n", n, ret);
  return 0;
}

方法三:

       这种方法比较难想,但是效率非常高,咱们举例说明,15的二进制表示为1111,15-1也就是14的二进制表示为1110,14-1也就是13的二进制表示为1101,以此类推,我们可以发现,任何数n和n-1的二进制之间只差了1位,而且这一位恰好就是0和1的区别,那么n与上(n-1)就可以消去一个1,也就是咱们每执行一次这样的操作,咱们就去掉了这个数二进制中的一个1,直到最后,这个数里面没有1了,那么数值也就变成了0,用计数器记录这个过程,最后就能得到我们想要的值

代码实现及详解

       经过了我们上述的分析,我们就可以这样做,当最后n中的1消完了,n就等于了0,0表示假,while语句循环停止,最后返回计数器里面的值

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int numberof1(int n)
{
  int count = 0;
  while (n)
  {
    n = n & (n - 1);
    count++;
  }
  return count;
}
int main()
{
  int n = 0;
  scanf("%d", &n);
  int ret = numberof1(n);
  printf("%d的二进制中1的个数为%d\n", n, ret);
  return 0;
}

程序运行结果图示

以上三种方法代码运行结果都是一样的,这里只是举例输出

目录
相关文章
|
2月前
leetcode2376. 统计特殊整数
leetcode2376. 统计特殊整数
15 1
|
2月前
《剑指offer》——二进制中1的个数
《剑指offer》——二进制中1的个数
|
4月前
|
Java C++ Python
试题 基础练习 查找整数
试题 基础练习 查找整数
15 0
【剑指offer】-二进制中1的个数-11/67
【剑指offer】-二进制中1的个数-11/67
|
5月前
|
存储 Java
剑指Offer LeetCode 面试题15. 二进制中1的个数
剑指Offer LeetCode 面试题15. 二进制中1的个数
28 0
|
11月前
剑指Offer - 面试题15:二进制中1的个数
剑指Offer - 面试题15:二进制中1的个数
50 0
|
11月前
LeetCode刷题集(一)(LeetCode1684统计一致字符串的数目)
LeetCode刷题集(一)(LeetCode1684统计一致字符串的数目)
45 0
|
11月前
|
机器学习/深度学习 C++
剑指offer 14. 二进制中1的个数
剑指offer 14. 二进制中1的个数
39 0
LeetCode每日一题——1684. 统计一致字符串的数目
给你一个由不同字符组成的字符串 allowed 和一个字符串数组 words 。如果一个字符串的每一个字符都在 allowed 中,就称这个字符串是 一致字符串 。
59 0