当前位置: 首页 > news >正文

(最全解法)输入一个整数,输出该数二进制表示中1的个数。

题目:请实现一个函数,输入一个整数,输出该整数二进制表示中1的个数。
例如:把9表示成二进制是1001,有2位是1.所以,如数该函数9,则输出2

  • 解法一
    容易造成死循环
    思路:先判断该数的二进制表示中最右边是不是1,再把输入的这个整数向右移动一位,此时原来处于右边第二位的数被放在了最右边,在判断是不是1;循环往复,直到输入的数字变为0为止。
    如何判断最右边位是不是1,我们把输入的整数与1采用按位与运算“&”,可知1的二进制只有最右边是1,按位与运算只有同为真时才为真也就是同为1时结果才为1。
    如此,输入的整数与1按位与运算结果位1,则表示最右边为1,否则为0.
int count_one_bits(int val)
{
	int count = 0;//计数
	int i = 0;
	for (i = 0; i < 32; i++)//一个整数占4个字节,内存中占32比特位
	{
		if ((val >> i) & 1 == 1)
			count++;
	}
	return count;
}
  • 解法二
    常规解法,不会死循环
    思路:避免死循环,不要移动输入的整数n。
    可以先把n与1做按位与运算,判断最低为是不是1。把1向左移动1位变成2,在与n那位与运算,这样就可以判断n的次低位是不是1,循环往复知道到n最高位判断完,1变成0,同时最为循环停止的条件。
int count_one_bits3(int val)
{
	int count = 0;
	int i = 0;
	//根据类型获取循环次数
	for (i = 1; i != 0; i <<= 1)
	{
		//把第i位移到第一位,和1进行按位与&运算,获取二进制值
		if ((val & i) != 0)
		{
			count++;
		}
	}
	return count;
}
  • 解法三
    利用奇偶数判断
    思路:奇数的最右边的一位绝对是1
int count_one_bits(int val)
{
	int count = 0;
	int i = 0;
	for (i = 1; i <= 32; i++)
	{
		//根据奇偶数判断第一位是否为1
		//奇数的第一位肯定为1
		if (val % 2 == 1)
		{
			count++;
		}
		//相当于右移,依次把其它位挪到第一位,再去判断
		val = val / 2;
	}
	return count;
}
  • 解法四
    新想法,效率最高有几个1就执行几次
    思路:把一个整数减去1,在于原数字做按位与运算,会把原数二级制位中最右边的1变成0.那么一个整数二进制表示中有几个1,就可以进行几次这样的操作。
    0111减去1变成0110,二者进行与运算变成0110,则把原数做右边的1变成0.循环往复直到全为0结束。
int count_one_bits4(int val)
{
	int count = 0;
	while (val)//到最后val变成0,退出循环
	{
		val = val&(val - 1);//把原数二进制位中做右边的1变为0
		count++;
	}
	return count;
}
总代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

/*统计一个整数的二进制中有几个1?*/

int count_one_bits(int val)
{
	int count = 0;
	int i = 0;
	for (i = 0; i < 32; i++)
	{
		if ((val >> i) & 1 == 1)
			count++;
	}
	return count;
}

int count_one_bits2(int val)
{
	int count = 0;
	int i = 0;
	for (i = 1; i <= 32; i++)
	{
		if (val % 2 == 1)
		{
			count++;
		}
		val = val / 2;
	}
	return count;
}

int count_one_bits3(int val)
{
	int count = 0;
	int i = 0;
	//根据类型获取循环次数
	for (i = 1; i != 0; i <<= 1)
	{
		//把第i位移到第一位,和1进行按位与&运算,获取二进制值
		if ((val & 1) == 1)
		{
			count++;
		}
		val >>= 1;
	}
	return count;
}

int count_one_bits4(int val)
{
	int count = 0;
	while (val)
	{
		val = val&(val - 1);
		count++;
	}
	return count;
}

int main()
{
	int val=0;
	int ret = 0;
	scanf("%d", &val);
	ret = count_one_bits(val);
	//ret=count_one_bits2(val);
	//ret=count_one_bits3(val);
	//ret=count_one_bits4(val);
	printf("%d\n",ret);
	system("pause");
	return 0;
}
运行截图:

结果

相关文章:

  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • 大小端(存储)模式辨析———数据的存储
  • memcpy()、memmove()函数的模拟实现———C语言
  • 结构体解析——— 自定义类型
  • 联合体和枚举——— 自定义类型
  • 结构体通讯录——C语言知识运用
  • 编译和宏的理解
  • 时间空间复杂度——详解
  • 【数据结构:队列】——队列的实现(C语言)
  • 【数据结构:栈】——栈的实现(C语言)
  • 【数据结构:链表】——无头单向非循环链表的实现(C语言)
  • 【数据结构:链表】——带头双向循环链表的实现(C语言)
  • 【数据结构:堆】——堆及堆的相关操作(C语言)
  • c++入门——基础知识点(1)
  • c/c++内存管理
  • JS 中的深拷贝与浅拷贝
  • #Java异常处理
  • [译] React v16.8: 含有Hooks的版本
  • 10个最佳ES6特性 ES7与ES8的特性
  • crontab执行失败的多种原因
  • CSS 提示工具(Tooltip)
  • JavaScript 一些 DOM 的知识点
  • Linux下的乱码问题
  • Mocha测试初探
  • Python 基础起步 (十) 什么叫函数?
  • 从0搭建SpringBoot的HelloWorld -- Java版本
  • 复习Javascript专题(四):js中的深浅拷贝
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 理清楚Vue的结构
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 使用Swoole加速Laravel(正式环境中)
  • 试着探索高并发下的系统架构面貌
  • 线性表及其算法(java实现)
  • 云大使推广中的常见热门问题
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • 组复制官方翻译九、Group Replication Technical Details
  • #14vue3生成表单并跳转到外部地址的方式
  • #ifdef 的技巧用法
  • #NOIP 2014# day.1 生活大爆炸版 石头剪刀布
  • #Spring-boot高级
  • (16)Reactor的测试——响应式Spring的道法术器
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (39)STM32——FLASH闪存
  • (4) PIVOT 和 UPIVOT 的使用
  • (6)STL算法之转换
  • (SpringBoot)第二章:Spring创建和使用
  • (二十四)Flask之flask-session组件
  • (排序详解之 堆排序)
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (十) 初识 Docker file
  • (十七)devops持续集成开发——使用jenkins流水线pipeline方式发布一个微服务项目
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿