写一个函数求某个数对应的二进制中1的个数(牛客)

news2024/11/27 10:33:40

[该题的牛客链接](https://www.nowcoder.com/questionTerminal/8ee967e43c2c4ec193b040ea7fbb10b8?
在这里插入图片描述


  • 一、方法一:%/达到二进制位右移的效果
    • 1.1用>>操作符实现
    • 1.2方法一代码的改进(针对负数情况)
  • 二、方法二:按位与1(&1)来判断最末位是否是1
  • 三、方法三:n = n&(n-1)——比较难想到的方法
    • 拓展——判断一个数是不是2的幂次方(非负整数)

一、方法一:%/达到二进制位右移的效果

//方法一
//         
//10 % 2 -> 0
//10 /= 2 -> 5 -> 101
// 
// 5 % 2 -> 1 -> count+1
// 5 /= 2 -> 2 -> 10
// 
// 2 % 2 -> 0
// 2 /= 2 -> 1 -> 1
// 
// 1 % 2 -> 1 -> count+1
// 1 /= 2-> 0 -> 跳出循环
//count得到就是2 
#include<stdio.h>

int Count(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 = Count(n);
	printf("%d\n", ret);
	return 0;
}

在这里插入图片描述
代码上方注释也给出了大概解释,这里我再用文字解释一下。
我们拿10举例,10的二进制是1010,共两个1
首先10%2得到结果为0,不做处理
然后再让10/=上2,得到结果为5,此时我们可以注意到,5的二进制是101
然后再让5%2,得到结果是1,此时让count加1
然后再让5/=2,得到结果为2,二的二进制是10
然后可以让2在%2得到结果为0,同样不做处理
然后2/=2得到结果为1,对应二进制就是1
然后1%2,结果是1,让count在加1
然后1/=2结果是0,最终跳出循环
我们可以发现,每次/=得到的二进制数从1010到101再到10最好到1,有种类似二进制数不断右移的效果,每次右移之后再判断末位是否为1就行,因此同样除了使用%/方法外,我们可以直接用>>来实现

1.1用>>操作符实现

//就是把/= 换成>>=,只是用/=更好理解一些
#include<stdio.h>

int Count(int n)
{
	int count = 0;
	while (n)
	{
		if (n % 2 == 1)
		{
			count++;
		}
		n >>= 1;
	}
	return count;
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = Count(n);
	printf("%d\n", ret);
	return 0;
}

1.2方法一代码的改进(针对负数情况)

回到最开始的代码,当我们输入负数时

会发现结果竟然是0,但是-1的补码是32个1呀,结果应该是32才对
那我们再来分析一下
-1 % 2 等于-1,count还是0
然后-1 /= 2等于 0,跳出循环,所以结果最终是0
改进代码:

#include<stdio.h>

int Count(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 = Count(n);
	printf("%d\n", ret);
	return 0;
}

在这里插入图片描述
分析:当形参用int时,-1传进去就还是-1,因为看作有符号数,就把-1的补码再转回源码得到-1
而当用unsigned int时,-1的补码就被当作无符号数了,所以转成源码就还是32个1了,可以正常计算1的个数了
但是但是,牛客的题目是接口类型的,形参类型已经给定是int了,所以这个代码还是无法通过

二、方法二:按位与1(&1)来判断最末位是否是1

#include<stdio.h>

int Count(unsigned int n)
{
	int count = 0;
	for (int i = 0; i < 32; i++)
	{
		if (1 == ((n >> i) & 1))
		{
			count++;
		}
	}
	return count;
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = Count(n);
	printf("%d\n", ret);
	return 0;
}

在这里插入图片描述
当然-1也是可以的
在这里插入图片描述
分析:

在这里插入图片描述
当一个数对应的二进制数补码末位为1时,该数&1结果为1,末位为0时结果为0
总结一个数&1能得到该二进制的最末位,该数|0(或上0)也可以达到该效果。

三、方法三:n = n&(n-1)——比较难想到的方法

首先,我们看看方法二里面的不足:不管二进制数中有几个1,循环都要执行32次,严重影响效率
改进:n = n&(n-1)
在这里插入图片描述
每个红框就是执行一次n = n&(n-1),当最终执行结果为0时停止,执行几次就代表最开始的n的二进制中有几个1
原理:每次的减一操作,能够将二进制最靠右的1给减掉,因为这个1的右边全是0,减一需要借位了,刚好把1给借掉,可以导致n和n-1的1、0错位,再&之后就全是0了,这样一套操作就能消除一个零
这个方法就能避免方法二的缺点,当计算1对应二进制位1的个数时只会执行一次!

拓展——判断一个数是不是2的幂次方(非负整数)

常规解法不写,写一个通过方法三拓展出来的方法
这题的关键是找到2的幂次方数的特点:对应的二进制数中1的个数为1,例如1——1,2——10,4——100,8——1000…所以只要n&(n-1)的结果等于0,就代表者只要一个1!

#include<stdio.h>

int Power(int n)
{
	return !(n & (n - 1));
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	if (Power(n))
	{
		printf("%d是2的幂次方", n);
	}
	else
	{
		printf("%d不是2的幂次方", n);
	}
	return 0;
}

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/724226.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于PyQt5的桌面图像调试仿真平台开发(14)色彩增强

系列文章目录 基于PyQt5的桌面图像调试仿真平台开发(1)环境搭建 基于PyQt5的桌面图像调试仿真平台开发(2)UI设计和控件绑定 基于PyQt5的桌面图像调试仿真平台开发(3)黑电平处理 基于PyQt5的桌面图像调试仿真平台开发(4)白平衡处理 基于PyQt5的桌面图像调试仿真平台开发(5)…

VSCode编译github上面的C++项目

1、下载cmake 在这里下载对应的版本 https://cmake.org/download/ 测试下载的是这个 下载完成后安装&#xff0c;安装都比较简单 2、安装CMake工具扩展 3、安装C扩展 4、下载github项目 例如&#xff1a;下载这个项目 https://gitcode.net/mirrors/zrax/pycdc?utm_source…

Axure教程—菜单滚动切换交互

本文接受的是用Axure中的动态面板和热区制作菜单滚动切换交互 效果 预览地址&#xff1a;https://u5ircj.axshare.com 功能 页面滚动到某一内容部分&#xff0c;显示其相应的菜单。 制作 一、所需元件 矩形、动态面板、热区 二、制作过程 拖入一个矩形元件&#xff0c;其大小…

CSO 们关注的软件供应链安全十个关键问题

写在前面 自从和几个小伙伴一起创办墨菲安全以来&#xff0c;有一年半多的时间了&#xff0c;创业对于我来说&#xff0c;很有意思的一个地方&#xff0c;就是有机会可以和各行各业很多非常有意思的人一起交流&#xff0c;在这个交流的过程中能够不断的提升自己的认知&#xf…

【Java基础教程】(四)程序概念篇 · 中:探索Java编程基础,解析各类运算符功能、用法及其应用场景~

Java基础教程之程序概念 中 本节学习目标1️⃣ 运算符1.1 关系运算符1.2 算术运算符1.3 三目运算符1.4 逻辑运算1.4.1 与操作1.4.2 或操作1.4.3 非操作 1.5 位运算&#x1f50d;位运算规则1.5.1 位与运算1.5.2 位或运算 &#x1f33e; 总结 本节学习目标 掌握Java中各类运算符…

MSF安装使用指导案例

零.简介 Metasploit&#xff08;MSF&#xff09;是一个免费的、可下载的框架&#xff0c;它本身附带数百个已知软件漏洞&#xff0c;是一款专业级漏洞攻击工具。当H.D. Moore在2003年发布Metasploit时&#xff0c;计算机安全状况也被永久性地改变了&#xff0c;仿佛一夜之间&a…

选择排序--简单选择排序,堆排序(大根堆,小根堆的建立,堆排序,插入删除元素)包含程序

选择排序&#xff1a;每一趟从待排序列中选择最小的元素作为有序子序列中的元素&#xff0c;待元素只剩下一个&#xff0c;就不用选了。 一&#xff0c;简单选择排序 1.过程&#xff1a;假设以A[]表示数组 1.1最开始定义一个变量用来存储数组数组第一个元素的序号 i 0; min…

赛效:怎么无损压缩Word文档

1&#xff1a;在电脑上打开PDF猫&#xff0c;在导航栏的“文件压缩”菜单里点击“Word压缩”。 2&#xff1a;点击或者拖拽Word文档上传。 3&#xff1a;文件添加成功后&#xff0c;点击右下角“开始转换”。 4&#xff1a;转换成功后&#xff0c;文件下方有下载按钮&#xff0…

快速搭建专属于自己的单商户商城系统!

<系统简介> 基于ThinkPHP6.0、Vue、uni-app、PHP8.0、MySQL5.7、element-ui等主流通用技术开发的一套likeshop单商户商城系统&#xff0c;真正做到好懂&#xff0c;易改&#xff0c;不绕弯 代码全开源 极易二开 可免费商用 系统适用于B2C、单商户、自营商城场景。完…

SOLIDWORKS电控柜设计插件

电控柜设备的种类有很多种&#xff0c;但它们大体都是箱柜式的结构。电控柜是有标准的&#xff0c;但对于公司产品而言&#xff0c;针对不同的项目&#xff0c;如果都使用同一种规格的电控柜&#xff0c;又有可能空间太大&#xff0c;造成浪费&#xff0c;因此一般来说&#xf…

Postman 连接/请求超时(远程服务/接口访问不上)

一、问题情况 二、解决思路 接口访问不了&#xff0c;先看请求方式&#xff0c;然后看IP地址&#xff0c;发现都对着&#xff0c;但请求接口对应的端口号发现连接不上&#xff0c;于是想到是不是防火墙没有关&#xff08;不过理论上严谨一点&#xff0c;是只要把这个端口给开放…

机器学习27:使用 Pandas 和 TensorFlow 进行数据建模编程实践

本文将详细介绍基于 Pandas 和 TensorFlow 探索、清理以及转换用于训练模型的数据集的方法&#xff0c;辅以代码和图片。 学习目标&#xff1a; 了解使用 Pandas 进行数据清理和处理丢失数据的基础知识。使用校准图评估模型性能。使用各种特征转换训练模型。使用可视化来了解…

前端学习——jsDay5

对象 对象使用 小练习 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"width…

科技力量赋予 SK5 代理 HTTP 代理 IP 网络无限可能

第一部分&#xff1a;智能网络加速技术 智能缓存&#xff1a;SK5 代理 HTTP 代理 IP 利用智能缓存技术&#xff0c;将经常访问的资源缓存在代理服务器中&#xff0c;从而实现更快速的资源加载和页面响应。这种智能化的缓存策略有效减少了对远程服务器的依赖&#xff0c;提升了用…

产品经理学习画原型-登录界面

开始画登录界面 选择一个矩形 常用修改&#xff1a; 选择文本标签&#xff1a; 设置字体、字号、颜色 添加水平线&#xff1a; 调整两个线连接&#xff0c;可以用CTRL加号、减号放大缩小画布来处理 选择一个主要按钮&#xff1a; 处理颜色、圆角 添加文本框&#xff1a; 设置高…

Android性能分析【启动优化】

作者&#xff1a;申国骏 性能分析工具 首先我们来学习一下如何使用性能分析的工具。我们从一个具体的例子出发&#xff0c;就是如何分析应用启动的性能。 Android Profiler 配置 我们来先看看Android Profiler。为了能在应用一启动就能马上捕捉到分析数据&#xff0c;我们需…

python接口自动化(十八)--重定向(Location)(详解)

简介 在实际工作中&#xff0c;有些接口请求完以后会重定向到别的url&#xff0c;而你却需要重定向前的url。URL主要是针对虚拟空间而言&#xff0c;因为不是自己独立管理的服务器&#xff0c;所以无法正常进行常规的操作。但是自己又不希望通过主域名的二级目录进行访问&#…

Linux下make和makefile的使用方法

1.make和makefile的区别 make是指令&#xff0c;makefile是文件&#xff0c;这是两者的却别。两者搭配使用&#xff0c;完成项目自动化创建。 2.make原理 make是如何工作的&#xff0c;也就是在默认情况下&#xff0c;我们只输入make命令&#xff0c;那么 1.make会在当前目录下…

Python基础:函数和函数式编程

文章目录 函数和函数式编程函数函数式编程 函数和函数式编程 函数 声明函数&#xff1a; def hello():print("hello function!")调用函数&#xff1a; # 使用()调用 hello()#output:hello function!# 没有()&#xff0c;则不进行调用&#xff0c;一切皆是对象&am…

Spring + Spring MVC + MyBatis+Bootstrap+Mysql酒店管理系统源码

IDEASpring Spring MVC MyBatisBootstrapMysql酒店管理系统源码 一、系统介绍1.环境配置 二、系统展示1. 管理员登录2.会员信息管理3.客房信息类型管理4.客房信息管理5.客房信息添加6.预定信息管理7.入住信息管理8.入住信息添加 三、部分代码UserMapper.javaUserController.j…