位运算小妙招-求二进制序列中0的个数

举报
芒果_Mango 发表于 2022/01/29 21:39:08 2022/01/29
【摘要】 💎二进制以1和0表示,这次,笔者将讲解另一个小妙招快速求解二进制序列中0的个数! 题目要求:🚗求一个二进制序列中二进制位为0的个数如:15 二进制序列0的个数为28 方法1:%2 /2 🛺二进制:只有0和1 所以我们可以求出二进制1的序列之后,相减int:4字节->32bit二进制序列中0的个数 = 32 - 二进制序列1的个数🛴%2 /2 判断条件不能写成 n%2 == 0 -...

💎二进制以1和0表示,这次,笔者将讲解另一个小妙招快速求解二进制序列中0的个数!


题目要求:

🚗求一个二进制序列中二进制位为0的个数

如:15 二进制序列0的个数为28


方法1:%2 /2

image.png

🛺二进制:只有0和1 所以我们可以求出二进制1的序列之后,相减

int:4字节->32bit

二进制序列中0的个数 = 32 - 二进制序列1的个数

🛴%2 /2 判断条件不能写成 n%2 == 0 ->count++ 然后返回count的值 因为偶数才符合n%2 == 0
🛵做法:求出二进制序列中1的个数之后,用32-去二进制序列1的个数得到的就是二进制序列中0的个数

size_t Binary_zero(size_t n)
{
    size_t count = 0;
    while (n)
    {
        if (n % 2 == 1)
        {
            count++;
        }
        n = n / 2;
    }
    return 32 - count;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	size_t ret = Binary_zero(n);
	printf("%d\n", ret);
}

🚎注意:当我们输入的是负数时,结果会出错,因为整数在内存中以补码形式存储,如果参数n定义为整形:负数时:会把补码->原码然后再参与下面的计算0的个数,这样就不符合要求! 所以我们可以把参数定义为无符号整数(size_t 即unsigned int),这样传参为负数时也不会出错!

🏍size_t :无符号整数,把内存中的补码当成原码看待

🚠打印16进制时也是把内存中的补码当成原码看待


方法2:得到每一位进行分别判断

image.png

🚇将二进制序列的每一个比特位分别判断

🚉**& : 0&1 = 0 1&1 = 1**

所以我们可以让二进制序列的每一位和1进行与运算,如果对于的二进制序列的位为1,那么结果就是1,反之则是0.

🚆右移(>>)得到每一位的二进制比特位之后,与1相与进行判断。使用计数器进行计数,如果相与的结果为1,计数器+1

右移:移动的是比特位.

size_t Binary_zero(int n)
{
	int i = 0;
	size_t count = 0;
	for (i = 0; i < 32; i++)
	{
		if ( ((n >> i) & 1) == 0)
		{
			count++;
		}
	}
	return count;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	size_t ret = Binary_zero(n);
	printf("%d\n", ret);
}

方法3-小妙招:x|(x+1)

✈x|(x+1) : 把二进制序列中最低位的0变成1

可以用此方法统计二进制序列中0的个数,每使用一次,就把内存中的最低位的0变成1,最后为全1序列 ->补码为全1 ->对应十进制值为-1

🚋只要统计通过几次使用,值变成-1,就知道二进制序列有多少个0

所以判断条件为:🚀 while(n != -1)

size_t Binary_zero(int n)
{
	size_t count = 0;
	while (n != -1)
	{
		n = n | (n +1);
		count++;
	}
	return count;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	size_t ret = Binary_zero(n);
	printf("%d\n", ret);
}

💖💕好了,今天就到这儿吧,欢迎大佬们点赞、收藏、评论呀!笔者水平有限,欢迎各位大佬批评指正!再次感谢!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。