位运算的相关内容

交换两个数

  • 当交换两个数时,一般情况下会开一个额外变量作为中介,或者是使用C++的swap,也或者利用数学特性进行交换

    int tmp=x;	//额外变量
    x=y;
    y=tmp;
    
    swap(x,y);	//调用swap
    
    x=x+y;	//数学
    y=x-y;
    x=x-Y
    

    同时我们也知道,异或:相同为假,不同为真。两个相同的数异或之后等于0,任何数与0异或等于其本身,所以我们可以推导出以下交换两个数的式子
    异或是支持交换律和结合律的

    x=x^y;
    y=x^y;
    x=x^y;
    

    仔细一看,三个式子中全部都带有x^y,做一下解释,第一个式子中将x^y的结果赋给了x,对于第二个式子,将第一个结果带入可得:x=x^y=(x^y)^y=x^(y^y)=x^0=x,这样就将x的值赋给了y,同理,第三个式子就将y的值赋给了x


找出没有重复的数

  • 例如:给你一串整型数,这些数中有的数重复出现了两次,但只有一个数出现了一次,让你求出这个数。
    前几条已经知道:两个相同的数异或结果为0,任何数与0异或都等于其本身。这样思路大致就有了:我们让所有的数都异或一遍,相同的数通过异或会等于0,0再与其他数字异或还是等于那个数字,所以最后异或结果就是那个只出现一次的数字了

    int search(int a[],int len)
    {
        int ans=a[0];
        for(int i=1;i<len;i++)
        ans^=a[i];
        return ans;
    }
    

快速幂

  • 快速幂也是用到了与运算的内容,这里就不多讲了


求不大于N的最大的2的幂指数

  • 朴素做法:

    int search(int N)
    {
        int ans=1;
        for(int i=1;ans<=N;i++) ans*=2;
        return ans/2;
    }
    

    我们也可以通过位运算来求解
    例如12的二进制为:00001100,我们要求的是:00001000的十进制为8,所以要求的数即为N的二进制表示中保留最高为1,其余变为0即可,下面给出代码

    N|=N>>1;
    N|=N>>2;
    N|=N>>4;
    N|=N>>8;
    N|=N>>16;	//32、64不同
    ...
    

    这样N二进制表示中最左边1右边所有的数都变为了1,即00001111,再让N>>1,整体右移一位,变为了00000111,然后N+1,变为了00001000,即为我们要求的数;也可以对00001111先+1,然后>>1,

    总代吗:

    	int search(int N)
    {
        N|=N>>1;
    	N|=N>>2;
    	N|=N>>4;
    	N|=N>>8;
    	N|=N>>16;
    	return (N+1)>>1;
    }
    

    如有出错之处,请您通知本人,本人将以感激的态度接受您的指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值