c++面试题(2)-----计算一个数字的二进制数中1的个数

  • 操作系统:ubuntu22.04
  • IDE:Visual Studio Code
  • 编程语言:C++11

题目描述:

请实现一个函数 int NumberOf1(int n),输入一个整数(可能为负数),输出该数二进制表示中 1 的个数。例如:

复制代码
把 9 表示成二进制是 1001,有 2 个 1;
把 -1 表示成二进制在补码形式下全是 1(32位系统下是 32 个 1)。

示例

bash 复制代码
输入: n = 9
输出: 2

输入: n = -1
输出: 32

解题思路

这个问题主要考察的是对 二进制和位运算的理解,以及如何处理 负数(补码表示)。

以下是几种常见解法:

方法一:逐位与操作(推荐)

cpp 复制代码
int NumberOf1(int n)
{
    int count = 0;
    while (n != 0)
    {
        ++count;
        n = n & (n - 1); // 消除最右边的一个 1
    }
    return count;
}

优点:

  • 不需要考虑正负;
  • 效率高,循环次数等于 1 的个数;
  • 利用了 n & (n - 1) 特性:每次消去一个 1。

方法二:右移判断每一位是否为 1

cpp 复制代码
int NumberOf1(int n) 
{
    int count = 0;
    unsigned int flag = 1; // 使用无符号数来避免右移时出错
    while (flag != 0)
    {
        if (n & flag)
            ++count;
        flag <<= 1;
    }
    return count;
}

说明:

  • 循环 32 次(32位整数);
  • 每次用 flag 来测试某一位是否为 1;
  • 对于负数也能正确处理(因为使用了无符号变量);

方法三:使用 C++ 内建函数(C++20 起)

如果你使用的是 C++20 或更高版本,可以使用标准库提供的函数:

cpp 复制代码
#include <bit>
int NumberOf1(int n) {
    return std::popcount(static_cast<unsigned int>(n));
}

说明:

  • std::popcount() 返回一个数中 1 的数量;
  • 需要将 int 强转为 unsigned int 来保证行为一致。

示例代码

cpp 复制代码
#include <iostream>

using namespace std;

class Solution {
public:
    int NumberOf1( int n )
    {
        int count = 0;
        while ( n != 0 )
        {
            ++count;
            n = n & ( n - 1 );  // 消除最右边的 1
        }
        return count;
    }
};

int main()
{
    Solution solution;
    cout << "9 中 1 的个数:" << solution.NumberOf1( 9 ) << endl;    // 输出 2
    cout << "-1 中 1 的个数:" << solution.NumberOf1( -1 ) << endl;  // 输出 32
    return 0;
}

运行结果

bash 复制代码
9 中 1 的个数:2
-1 中 1 的个数:32
相关推荐
sin_hielo几秒前
leetcode 1266
数据结构·算法·leetcode
羑悻的小杀马特3 分钟前
etcd实战指南:从安装集群到C++封装,解锁分布式服务治理的“钥匙”
c++·分布式·etcd·集群
星火开发设计6 分钟前
C++ deque 全面解析与实战指南
java·开发语言·数据结构·c++·学习·知识
点云SLAM9 分钟前
C++设计模式之单例模式(Singleton)以及相关面试问题
c++·设计模式·面试·c++11·单例模式(singleton)
neardi临滴科技10 分钟前
从算法逻辑到芯端落地:YOLO 目标检测的进化与瑞芯微实践
算法·yolo·目标检测
小雨下雨的雨10 分钟前
Flutter跨平台开发实战:鸿蒙系列-循环交互艺术系列——瀑布流:不规则网格的循环排布算法
算法·flutter·华为·交互·harmonyos·鸿蒙系统
小雨下雨的雨12 分钟前
Flutter跨平台开发实战: 鸿蒙与循环交互艺术:跑马灯的无极滚动算法
算法·flutter·华为·交互·harmonyos·鸿蒙
草莓熊Lotso15 分钟前
Qt 信号与槽深度解析:从基础用法到高级实战(含 Lambda 表达式)
java·运维·开发语言·c++·人工智能·qt·数据挖掘
脏脏a1 小时前
C++ STL list 模拟实现:从底层链表到容器封装
开发语言·c++·stl·双链表
NAGNIP8 小时前
一文搞懂机器学习中的特征降维!
算法·面试