剑指offer——二进制中1的个数

news2024/11/28 6:34:06

目录

  • 1. 题目描述
  • 2. 可能引起死循环的想法
  • 3. 改进后的代码
  • 4. 给面试官惊喜的代码

1. 题目描述

  • 请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制位1001,有2位是1,因此如果输入9,该函数输出2.
  • 可以进这个链接练习——牛客网

2. 可能引起死循环的想法

  • 这是一道很基本的考查二进制和位运算的面试题。
  • 题目不是很难,面试官提出问题之后,我们很快就能形成一个基本的思路:先判断整数二进制表示中最右边一位是不是1。
  • 接着把输入的整数右移一位,此时原来处于从右边数起的第二位被移到最右边了,再判断是不是1。
  • 这样每次移动一位,直到整个整数变成0为止。现在的问题变成怎么判断一个整数的最右边是不是1了。
  • 这很简单,只要把整数和1做位与运算看结果是不是0就知道了。
  • 1除了最右边的一位之外所有位都是0。
  • 如果一个整数与1做与运算的结果是1,表示该整数最右边一位是1,否则是0。
  • 基于这个思路,我们很快就能写出如下代码:
#include <stdio.h>

int NumberOf1(int n)
{
	int count = 0;
	
	while (n != 0)
	{
		if (n & 1)
		{
			count++;
		}
		n >>= 1;
	}
	return count;
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	printf("%d\n", NumberOf1(n));
	return 0;
}
  • 当输入 9 时:

在这里插入图片描述

  • 面试官看了代码之后可能会问:把整数右移一位和把整数除以2在数学上是等价的,那上面的代码中可以把右移运算换成除以2吗?答案是否定的。
  • 因为除法的效率比移位运算要低得多,在实际编程中应尽可能地用移位运算符代替乘除法。
  • 面试官接下来可能要问的第二个问题就是:上面的函数如果输入一个负数,比如 0x80000000,运行的时候会发生什么情况?
  • 把负数0x80000000右移一位的时候并不是简单地把最高位的1移到第二位变成0x40000000而是0xC0000000。
  • 这是因为移位前是个负数,仍然要保证移位后是个负数,因此移位后的最高位会设为1。
  • 如果一直做右移运算,最终这个数字就会变成FFFFFFFF陷入死循环
  • 当输入-1时:

在这里插入图片描述

3. 改进后的代码

  • 为了避免死循环,我们可以不右移输入的数字 n。
  • 首先把 n 和 1 做与运算,判断 n 的最低为是不是 1。
  • 接着把 1 左移一位得到 2 ,再和 n 做与运算,就能判断 n 的次低位是不是 1……这样反复左移,每次都能判断 n 的其中一位是不是 1 了
  • 基于这个思路,我们可以把代码修改如下:
#include <stdio.h>

int NumberOf1(int n)
{
	int count = 0;
	unsigned int flag = 1;
	
	while (flag != 0)
	{
		if (n & flag)
		{
			count++;
		}
		flag <<= 1;
	}
	return count;
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	printf("%d\n", NumberOf1(n));
	return 0;
}
  • 当输入 9 时:

在这里插入图片描述

  • 当输入 -1 时:

在这里插入图片描述

4. 给面试官惊喜的代码

  • 在分析这种算法之前,我们先来分析把一个数减去1的情况。
  • 如果一个整数不等于0,那么该整数的二进制表示中至少有一位是1。
  • 先假设这个数的最右边一位是1,那么减去1时,最后一位变成0而其他所有位都保持不变。
  • 也就是最后一位相当于做了取反操作,由1变成了0。
  • 接下来假设最后一位不是1而是0的情况。
  • 如果该整数的二进制表示中最右边1位于第m位,那么减去1时,第m位由1变成0,而第m位之后的所有0都变成1,整数中第m位之前的所有位都保持不变。
  • 举个例子:一个二进制数1100,它的第二位是从最右边数起的一个1。减去1后,第位变成0,它后面的两位0变成1,而前面的1保持不变,因此得到的结果是1011。
  • 在前面两种情况中,我们发现把一个整数减去1,都是把最右边的1变成0。
  • 如果它的右边还有0的话,所有的0都变成1,而它左边所有位都保持不变。
  • 接下来我们把一个整数和它减去1的结果做位与运算,相当于把它最右边的1变成0。
  • 还是以前面的1100为例,它减去1的结果是1011。
  • 我们再把1100和1011做位与运算,得到的结果是1000。我们把1100最右
  • 边的1变成了0,结果刚好就是1000。
  • 我们把上面的分析总结起来就是:把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0。
  • 那么一个数的二进制表示中有多少个1,就可以进行多少次这样的操作。基于这种思路,我们可以写出新的代码:
#include <stdio.h>

int NumberOf1(int n)
{
	int count = 0;
	
	while (n != 0)
	{
		n = n & (n - 1);
		count++;
	}

	return count;
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	printf("%d\n", NumberOf1(n));
	return 0;
}
  • 运行结果为:

在这里插入图片描述
最后,
恭喜你又遥遥领先了别人!

在这里插入图片描述

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

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

相关文章

Javaweb之SpringBootWeb案例之AOP概述及入门的详细解析

2.1 AOP概述 什么是AOP&#xff1f; AOP英文全称&#xff1a;Aspect Oriented Programming&#xff08;面向切面编程、面向方面编程&#xff09;&#xff0c;其实说白了&#xff0c;面向切面编程就是面向特定方法编程。 那什么又是面向方法编程呢&#xff0c;为什么又需要面向…

概率论中不确定性的来源-简单不确定的规则

更多AI技术入门知识与工具使用请看下面链接&#xff1a; https://student-api.iyincaishijiao.com/t/iNSVmUE8/

openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存

文章目录 openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存217.1 查看内存状况217.2 性能参数分析 openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存 获取openGauss节点的CPU、内存、I/O和网络资源使用情况&…

酒店押金预授权怎么开通?微信酒店押金+房态+门锁关联 +电子押金单 解决方案

一、酒店押金管理有哪些&#xff1f; 1.渠道有银行预授权 2.微信押金支付 3.酒店押金系统 4.支付押金管理 二、银行预授权模式 酒店押金预授权通常是在客人办理入住时进行的&#xff0c;酒店会要求客人提供信用卡或借记卡的卡号、有效期、持卡人姓名等信息&#xff0c;然后…

Vue源码系列讲解——模板编译篇【三】(HTML解析器)

目录 1. 前言 2. HTML解析器内部运行流程 3. 如何解析不同的内容 3.1 解析HTML注释 3.2 解析条件注释 3.3 解析DOCTYPE 3.4 解析开始标签 3.5 解析结束标签 3.6 解析文本 4. 如何保证AST节点层级关系 5. 回归源码 5.1 HTML解析器源码 5.2 parseEndTag函数源码 6. …

js toFixed函数精度问题

在使用toFixed函数会出现精度缺失问题&#xff0c;如下图 在2.55与1.45保留1位小数时&#xff0c;正常情况下应该为2.6与1.5&#xff0c;而toFixed函数得出的是2.5与1.4。这和计算机中小数存储有关。 小数运算不精确其实与下面三方面有关&#xff1a; 1、存储 2、运算 3、显示…

新项目,从0到1,SpringBoot+Vue.js权限管理系统,拿去做毕设

大家好&#xff0c;我是 jonssonyan 最近把以前做的权限管理系统重新整理了一下&#xff08;将一些不规范的地方规范了一下&#xff0c;并且在关键地方写了注释&#xff09;&#xff0c;代码全部开源&#xff0c;这个项目是以现在主流的前后端分离模式开发的&#xff0c;包含前…

课时27:内容格式化_输入格式化_EOF原理

3.2.1 EOF原理 学习目标 这一节&#xff0c;我们从 基础知识、简单实践、小结 三个方面来学习。 基础知识 场景需求 在运维岗位中&#xff0c;有非常多的场景需要我们在脚本中编写应用软件的配置文件。在这些应用软件的配置文件中&#xff0c;经常携带大量的格式&#xff0…

猫头虎分享已解决Bug || SyntaxError: Unexpected token o in JSON at position 1 ‍

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

Docker 镜像是什么?常用的镜像命令有哪些?

docker 镜像仓库相关的命令&#xff1a;Docker 镜像仓库是什么&#xff1f;有哪些镜像仓库命令&#xff1f;-CSDN博客 1. Docker 镜像 Docker 镜像是一个轻量级、独立、可执行的软件包&#xff0c;它包含了运行特定应用程序所需的所有内容&#xff1a;代码、运行时环境、系统工…

[计算机网络]---网络编程套接字

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、基础知识…

Web基础01-HTML+CSS

目录 一、HTML 1.概述 2.html结构解析 3.HTML标签分类 4.HTML标签关系 5.HTML空元素 6.HTML属性 7.常用标签 &#xff08;1&#xff09;HTML标签 &#xff08;2&#xff09;标题标签 &#xff08;3&#xff09;换/折行标签 &#xff08;4&#xff09;段落标签 &am…

Qt之条件变量QWaitCondition详解

QWaitCondition内部实现结构图&#xff1a; 相关系列文章 C之Pimpl惯用法 目录 1.简介 2.示例 2.1.全局配置 2.2.生产者Producer 2.3.消费者Consumer 2.4.测试例子 3.原理分析 3.1.辅助函数CreateEvent 3.2.辅助函数WaitForSingleObject 3.3.QWaitConditionEvent …

java客运管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java客运管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&#…

国产制造,欧美品质:爱可声助听器产品质量获国际认可

随着科技的发展和全球化的推进&#xff0c;越来越多的中国制造产品开始走向世界舞台。其中&#xff0c;爱可声助听器凭借其卓越的产品质量&#xff0c;成为了国产制造的骄傲。 国产制造指的是在中国境内生产的产品&#xff0c;欧美品质则是指产品在设计、生产、质量控制等方面…

不止于浏览器:掌握Node.js,开启全栈开发新篇章!

介绍&#xff1a;Node.js是一个基于Chrome V8引擎的JavaScript运行时环境&#xff0c;特别适合构建高性能的网络服务器和实时应用。具体介绍如下&#xff1a; 服务器端JavaScript&#xff1a;Node.js的核心优势之一是在服务器端运行JavaScript&#xff0c;这使得前端开发者可以…

KAJIMA CORPORATION CONTEST 2024(AtCoder Beginner Contest 340)ABCDEF 视频讲解

这场比较郁闷&#xff0c;C题短路&#xff0c;连续4次WA&#xff0c;导致罚时太多 A - Arithmetic Progression Problem Statement Print an arithmetic sequence with first term A A A, last term B B B, and common difference D D D. You are only given inputs for w…

【论文模型讲解】CLIP(Learning Transferable Visual Models From Natural Language Supervision)

文章目录 前言0 摘要1 Introduction and Motivating Work2 Approach2.0 模型整体结构2.1 数据集2.2 选择一种高效的预训练方法2.3 模型选择与缩放2.4 训练 3 实验3.1 zero-shot 迁移3.1.1 与 Visual N-grams 对比3.1.2 Prompt Engineering and Ensembling3.1.3 zero-shot CLIP …

【数据结构】哈希桶封装出map和set

利用之前的哈希桶封装出unordered_map和unordered_set。 这个封装并不简单&#xff0c;迭代器的使用&#xff0c;模板参数的繁多&#xff0c;需要我们一层一层封装。 map是一个k - v类型&#xff0c;set是k类型&#xff0c;那么就明确了如果需要封装&#xff0c;底层的tables…

产品经理面试题解析:业务架构是通往成功的关键吗?

大家好&#xff0c;我是小米&#xff01;今天我要和大家聊的是产品经理面试中的一个热门话题&#xff1a;“业务架构”&#xff01;相信不少小伙伴在准备面试的时候都会遇到这个问题&#xff0c;究竟什么是业务架构&#xff1f;它又与产品经理的工作有着怎样的关系呢&#xff1…