操作符一些代码题

发布于:2022-12-22 ⋅ 阅读:(483) ⋅ 点赞:(0)

一 统计二进制中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;
}

代码如上

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

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

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

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

可是 如果是负数呢?

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

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

这样子代码就会出错了

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

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

代码如下

int get_count1(unsigned n)

如果说题目中规定死了 必须要输入一个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;
}

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

方法二

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

对于一个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;
}

然而这个代码有一个缺点

就是要计算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;
}

求二进制中不同位的个数

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

相同为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;
}

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

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

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

那么大家下期再见咯

本文含有隐藏内容,请 开通VIP 后查看