学习笔记20-经典面试题-求一个整数中1的个数

本文探讨了计算整数二进制表示中1的数量的四种不同方法。包括直接除法转换、考虑负数情况、位移操作以及优化后的位移方法。这些方法不仅适用于正数也适用于负数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

今天看到一个面试题,挺有趣的,分享一下。
请实现一个函数,输入一个整数,输出该整数的二进制表示中1的个数。
比如输入9,输出2。

解法1:除法

首先我想到的是用除法,也就是把十进制数转换成二进制数,计算1的个数

int count1(int n)
{
    int c=0;
    while(n>0)
    {
        if(n%2==1)
            c++;
        n/=2;
    }
    return c;
}

这个方法,在输入整数的时候没有任何问题,但是没有考虑到负数的情况,因为循环条件是n>0,所以所有负数都会输出0。

解法2:考虑负数

因为负数的符号位是1,所以负数的1的个数要比它的相反数加1。

int count1(int n)
{
    int c=0;
    if(n<0)
    {
        c++;
        n=-n;
    }
    while(n>0)
    {
        if(n%2==1)
            c++;
        n/=2;
    }
    return c;
}

解法3:位移

其实除法要比位移的运算效率慢很多,所以我们可以使用位移来代替。

int count2(int n)
{
    int c=0;
    unsigned int flag=1;
    while(flag)
    {
        if(n&flag)
            c++;
        flag=flag<<1;
    }
    return c;
}

解法4:位移

解法3已经有优化了,但是还可以优化,减小比较次数。解法3比较的次数等于一个int类型的位数,解法4比较的次数恰好等于1的个数。

int count3(int n)
{
    int c=0;
    while(n)
    {
        c++;
        n=(n-1)&n;
    }
    return c;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值