• 操作符一些代码题


    一 统计二进制中1的个数

    方法一

    我们来将这个问题幼儿园化一下

    求出一个十进制数字的所有位数

    是不是发现这个问题特别熟悉

    是的 在我们以前的博客中遇到过

    只需要不停的模10 除10就可以

    那么在二进制当中

    我们就只需要不停的模2除2就可以

    求出每一位数之后可以再来判断每一位数是不是1

    如果是1 count++

    如果 不是 就看下一个数

    int get_count1(int n)
    {
    	int count = 0;
    	while (n)
    	{
    		if (n%2==1)
    		{
    			count++;
    		}
    		n =n / 2;
    
    	}
    	return count;
    }
    
    
    
    
    
    
    int main()
    {
    	int n = 0;
    	scanf("%d", &n);
    	int ret = get_count1(n);
    	printf("%d\n",ret);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    代码如上

    博主写这个代码的时候出现了一个小错误

    n/2的值忘记赋值给n了 最终导致了进入死循环

    大家写代码的时候一定要注意啊

    这里我们可以计算出一个正数的2进制值

    可是 如果是负数呢?

    在这里插入图片描述
    我们可以发现 运行结果如上

    -1除以2确实是商0余负1啊

    这样子代码就会出错了

    那么有没有什么办法可以解决这个错误呢?

    当然有 只需要当-1强制类型转换成无符号数就好了

    代码如下

    int get_count1(unsigned n)
    
    • 1

    如果说题目中规定死了 必须要输入一个int类型的参数 有没有办法解决呢?

    当然也有

    在函数内部重新定义一个参数强制类型转换就可以

    参考代码如下

    int get_count1(int n)
    {
    	int count = 0;
    	unsigned m = (unsigned)n;
    	while (m)
    	{
    		if (m%2==1)
    		{
    			count++;
    		}
    		m =m / 2;
    
    	}
    	return count;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述
    我们可以发现 代码可以完美运行

    方法二

    我们在上一节课学习了 位操作符

    对于一个32位的数来说 我们只需要把它的每一位都拿出来

    然后和1比较

    比较个32次 就可以得到

    难点就在于怎么将它的每一位取出来呢?

    我们可以这样子 将它的&一个1

    这样就能得到最后一个数字的值

    然后我们再将这个数字右移一位 就可以拿到下一位数

    之后继续比较 最终得到1有多少个

    参考代码如下

    int get_count1(int x)
    {
    	int count = 0;
    	int i = 0;
    	for ( i = 0; i < 32; i++)
    	{
    		if ((x >> i) & 1 == 1)
    			count++;
    	}
    	return count;
    }
    
    
    int main()
    {
    	int n = 0;
    	scanf("%d", &n);
    	int ret =get_count1(n);
    	printf("%d\n", ret);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    然而这个代码有一个缺点

    就是要计算32次才可以 那么 有没有一个更加简单的方法呢?

    答案是有的

    方法三

    在二进制中 计算有多少个1可以使用这个公式
    n&(n-1)之后将它的结果赋值给n
    上面这一段代码执行多少次 就代表这个二进制数字n中有多少个1

    这也是目前为止最完美的解法

    代码如下

    int get_count1(int x)
    {
    	int count = 0;
    	while (x)
    	{
    		x = x & (x - 1);
    		count++;
    	}
    }
    
    int main()
    {
    	int n = 0;
    	scanf("%d", &n);
    	int ret = get_count1(n);
    	printf("%d\n", ret);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    求二进制中不同位的个数

    我们在上一篇博客中学习了^ 按位异或这个操作符

    相同为0 不同为1

    所以我们对这两个数使用^操作符 然后再统计其中1的个数 然后就可以完成求不同位的个数

    我们统计1个数的解决方案以及再上面了

    这里只需要套用一下就可以啦

    int get_count1(int x)
    {
    	int count = 0;
    	while (x)
    	{
    		x = x & (x - 1);
    		count++;
    	}
    }
    
    int main()
    {
    	int n = 0;
    	int m = 0;
    	int x = 0;
    	scanf("%d %d", &n, &m);
    	x = m ^ n;
    	int ret = get_count1(x);
    	printf("%d\n", ret);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    运行结果如下图所示
    在这里插入图片描述

    以上就是本篇博客的全部内容啦 由于博主才疏学浅 所以难免会出现纰漏 希望大佬们看到错误之后能够

    不吝赐教 在评论区或者私信指正 博主一定及时修正

    那么大家下期再见咯

  • 相关阅读:
    Golang学习之路6-goroutine并发
    【Linux 内核系列】基于 VMware Ubuntu18 编译调试 Linux 内核
    【React】React组件生命周期以及触发顺序(部分与vue做比较)
    【后端】HTTP3
    GitHub平台 Bookget操作
    linux系统文件权限
    TortoiseSVN小乌龟的使用
    java毕业设计—— 基于java+JSP+SSH的任务调度系统设计与实现——任务调度系统
    Pytest框架和Unittest框架的区别
    深度学习-卷积神经网络-ResNET
  • 原文地址:https://blog.csdn.net/meihaoshy/article/details/126792740