【解题报告】《算法零基础100讲》(第42讲) 位运算 (位与) 入门

前言

这一节主要讲位运算的位与
如果对位运算一点也不熟悉的朋友,可以看这篇文章,看完可了解基本概念,非常好用:

原文链接:《位操作》

位与的应用

1.判断奇偶性

正常的判断奇偶性代码是这样的:
比如要判断奇数

bool is_odd(int num)
{
	if (num % 2 == 1)
	{
		//奇数
		return true;
	}
	else
	{
		//偶数
		return false;
	}
}

而利用位操作也可以

代码:

bool is_odd(int num)
{
	if (num & 1 == 1)
	{
		//奇数
		return true;
	}
	else if (num & 1 == 0)
	{
		//偶数
		return false;
	}
}

原因:一个数字的二进制表示,末尾不是1就是0,所以与 1 进行与运算,即可判断奇偶性。

2. 2的幂判定

给定一个数字,那么可以利用下面的代码来判断此数字是否为偶数

	(x & (x - 1)) == 0

直接看图:

在这里插入图片描述

3. 计算二进制数中“1”的个数

代码:

	int hammingWeight(uint32_t n)
    {
        int count = 0;
        while (n)
        {
            n &= (n - 1);
            ++count;
        }    

        return count;
    }

图示:
对当前数字一直减一再位与,到最后为零

在这里插入图片描述

__builtin_popcount()

这个函数可以直接计算二进制数中“1”的个数。。。

习题

序号题目
1191. 位1的个数
2剑指 Offer 15. 二进制中1的个数
3231. 2 的幂
41356. 根据数字二进制下 1 的数目排序
5762. 二进制表示中质数个计算置位

题解

191. 位1的个数

原题链接:191. 位1的个数

在这里插入图片描述

代码

class Solution {
public:
    int hammingWeight(uint32_t n)
    {
        int count = 0;
        while (n)
        {
            n &= (n - 1);
            ++count;
        }    

        return count;
    }
};

剑指 Offer 15. 二进制中1的个数

原题链接:剑指 Offer 15. 二进制中1的个数

在这里插入图片描述

代码

class Solution {
public:
    int hammingWeight(uint32_t n)
    {
        int count = 0;
        while (n)
        {
            n &= (n - 1);
            ++count;
        }    
        return count;
    }
};

231. 2 的幂

原题链接:231. 2 的幂

在这里插入图片描述

法一:换底公式(log)

class Solution {
public:
    bool isPowerOfTwo(int n)
    {
        if (n <= 0) return false;

        int x = (int)(log2(n) / log2(2) + 1e-8);
        return fabs(n - pow(2, x)) < 1e-8;
    }
};

法二:位运算

bool isPowerOfTwo(int n)
{
    return n > 0 && (n & (-n)) == n;
}
bool isPowerOfTwo(int n)
{
    return (n > 0 && (n & (n - 1)) == 0);
}

1356. 根据数字二进制下 1 的数目排序

原题链接:1356. 根据数字二进制下 1 的数目排序

在这里插入图片描述

代码

修改 sort()

int num_of_one(int n)
    {
        int count = 0;
        while (n)
        {
            n &= (n - 1);
            ++count;
        }

        return count;
    }

    bool compare(int a, int b)
    {
        return (num_of_one(a) < num_of_one(b) || num_of_one(a) == num_of_one(b) && a < b);
    }

class Solution {
public:

    vector<int> sortByBits(vector<int>& arr)
    {
        sort(arr.begin(), arr.end(), compare);
         
        return arr;
    }
};

762. 二进制表示中质数个计算置位

原题链接:762. 二进制表示中质数个计算置位

在这里插入图片描述

在这里插入图片描述

分析

题目是要求:
给定范围内,每个数的二进制的1的个数是否为质数,计算它们的数目。

做法:根据题目范围,申请一个数组用来表示是否为质数。

int isprimer[20] = {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1};

遍历一遍,对每个数字求二进制1的个数,再去数组中查看是否为质数。

代码

class Solution {
public:
    int countPrimeSetBits(int left, int right)
    {
        int isprimer[20] = {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1};
        int ans = 0;

        for ( ; left <= right; ++left)
        {
            ans += isprimer[__builtin_popcount(left)];
        }

        return ans;
    }
};

end

原文链接: 《算法零基础100讲》(第42讲) 位运算 (位与) 入门

作者:英雄哪里出来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_索伦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值