位运算(基础)

前言
众所周知,位运算是我们学计算机必学的东西,前人用二进制、位运算给我们了一个操作简单的计算机,但我们却很少接触位运算了。今天介绍一些位运算在算法中的运用。

位运算基础
&
按位与
如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
|
按位或
两个相应的二进制位中只要有一个为1,该位的结果值为1
^
按位异或
若参加运算的两个二进制位值相同则为0,否则为1
~
取反
~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1
<<
左移
用来将一个数的各二进制位全部左移N位,右补0
&gt; &gt; &gt;&gt; >>
右移
将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数, 高位补0
奇技淫巧
1.技巧一:用于消去x的最后一位的1

 x & (x-1)
x = 1100
x-1 = 1011
x & (x-1) = 1000

1.1.应用一 用O(1)时间检测整数n是否是2的幂次.
思路解析:N如果是2的幂次,则N满足两个条件。
1.N>0
2.N的二进制表示中只有一个1
一位N的二进制表示中只有一个1,所以使用N&(N-1)将唯一的一个1消去。
如果N是2的幂次,那么N&(N-1)得到结果为0,即可判断。
1.2.应用二 计算在一个 32 位的整数的二进制表示中有多少个 1.
思路解析:
由 x & (x-1) 消去x最后一位知。循环使用x & (x-1)消去最后一位1,计算总共消去了多少次即可。
1.3.将整数A转换为B,需要改变多少个bit位
思路解析
这个应用是上面一个应用的拓展。
思考将整数A转换为B,如果A和B在第i(0<=i<32)个位上相等,则不需要改变这个BIT位,如果在第i位上不相等,则需要改变这个BIT位。所以问题转化为了A和B有多少个BIT位不相同。联想到位运算有一个异或操作,相同为0,相异为1,所以问题转变成了计算A异或B之后这个数中1的个数。

给定一个整数,编写一个函数来判断它是否是 2 的幂次方。
示例 1:
输入: 1
输出: true
解释: 2^0 = 1

运用位运算就可以很快的解出来。
因为2的幂次都是1,10,100,1000,10000
所以如果是2的幂次,则n&(n-1)=0
代码如下:

class Solution {
public:
    bool isPowerOfTwo(int n) {
        if(n <= 0 ) return false;
        return !(n&(n-1)); 
    }
};

例二:
求 a 的 b 次方对 p 取模的值。
输入格式
三个整数 a,b,p ,在同一行用空格隔开。
输出格式
输出一个整数,表示a^b mod p的值。
数据范围
1≤a,b,p≤109
输入样例:

3 2 7

输出样例:

2

解题思路1:
(暴力枚举) O(m)O(m)
暴力枚举也就是循环一遍即可

#include <iostream>
using namespace std; 
#define ll long long //自定义ll为long long类型 
int main()
{
    ll a,b,c,ans=1;
    cin>>a>>b>>c;
    for (ll i=1;i<=b;i++)
        ans=ans*a%c;
    cout<<ans;
}

解题思路2:
大致思路:我们知道,任何一个自然数都可以写成

  n=2^pi1+2^pi2+2^pi3+……2^pim

其中所有pi为非负整数,所以可以利用二分,将这一题次数m,转化一下即可

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring> 
using namespace std;
#define ll long long
ll n,m,k;
ll power(ll n,ll m,ll k)
{
    ll ans=1%k;
    while(m)
    {
        if (m&1)//如果m为奇数
            ans=ans*n%k;
        n=n*n%k;//将上一次的n进行平方
        m>>=1;
    }
    return (ans%k);
}
int main()
{
    cin>>n>>m>>k;
    n%=k;
    cout<<power(n,m,k);
} 

十进制数转换为2进制数

	while(n > 0){
		arr[j] = (n & 1);
		n >>= 1;
		j = j + 1;
	}
	for(int i = j - 1;i >= 0 ;i--){
		cout << arr[i];
	}

关于进制转换的例题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值