• C语言,求一个十进制数的二进制中1出现的次数,版本2.0(另外两种方法介绍)


    十进制的数字要分离十进制的每一位,要先模上10,获取个位数,接着除以十,将每一个位数都降低一级。再模上十,获取下一位数上的数字,再模上10……以此类推。

    而二进制要获得每一位数,也是一样的。先模上2,获取第一位数,接着除以2,将位数降低。接着再模2,再除2……直到全部转化为二进制。

    1. #include
    2. int fun(int n)
    3. {
    4. int count = 0;
    5. while (n)
    6. {
    7. if (n % 2 == 1)
    8. {
    9. count++;
    10. }
    11. n /= 2;
    12. }
    13. return count;
    14. }
    15. //这种方法不适用于负数
    16. int main()
    17. {
    18. int n = 0;
    19. scanf("%d", &n);
    20. int count = fun(n);
    21. printf("%d", count);
    22. return 0;
    23. }

     每一次循环判断到求得的相应位数为1(即n % 2 为1)时,count就会加一。

    但是这种方法有一个缺点,如果n为负数,count的值就会为零,因为count在count++之后就会变成0,而0进入到循环的判断条件中,就会终止循环。

    -1的补码应该是32个一,结果应该为32。

    正确做法是将函数接收到的参数n转化为无符号整型,如此-1就不会因为二进制的第一位被函数解读为负数了。

    如图:

    1. #include
    2. int fun(unsigned int n)
    3. {
    4. int count = 0;
    5. while (n)
    6. {
    7. if (n % 2 == 1)
    8. {
    9. count++;
    10. }
    11. n /= 2;
    12. }
    13. return count;
    14. }
    15. //这种方法不适用于负数
    16. int main()
    17. {
    18. int n = 0;
    19. scanf("%d", &n);
    20. int count = fun(n);
    21. printf("%d", count);
    22. return 0;
    23. }

    用按位与&实现的方法在我之前的博客中写过了,但是无论是按位与的方法还是上面的方法,当n够大的时候,都要进行多次计算。

    有没有一种方法能有多少个一就计算多少次呢,这种方法比较难想到,但是代码本身比较简单。

    1. #include
    2. int fun(int n)
    3. {
    4. int count = 0;
    5. while (n)
    6. {
    7. n = n & (n - 1);
    8. count++;
    9. }
    10. //101011
    11. //101010
    12. //按位与 第一次
    13. //101010
    14. //101001
    15. //按位与 第二次
    16. //101000
    17. //100111
    18. //按位与 第三次
    19. //100000
    20. //000001
    21. //按位与 第四次
    22. //000000
    23. //结果为四
    24. return count;
    25. }
    26. int main()
    27. {
    28. int n = 0;
    29. scanf("%d", &n);
    30. int count = fun(n);
    31. printf("%d", count);
    32. return 0;

    这里利用里二进制逢二进一的特点,每当一位数是1后面位数都是0时,减去一就是让其位数变成0。再利用按位与的特点,只有位数都为一时,结果位数才为1。

  • 相关阅读:
    spacy的每个词token的所有属性
    New SQL
    LeetCode 0795. 区间子数组个数
    正点原子嵌入式linux驱动开发——Linux设备树
    类隔离实现之自定义类加载器
    FTP无法在资源管理器中打开
    java: 错误: 无效的源发行版:17 【解决】
    linux常用命令
    java计算机毕业设计小区宠物管理系统源码+系统+数据库+lw文档
    初级项目经理 如何快速提升能力?
  • 原文地址:https://blog.csdn.net/2302_79468488/article/details/133829016