首页 > 其他 > 详细

利用位运算可以解决的一些问题

时间:2020-05-29 21:48:32      阅读:55      评论:0      收藏:0      [点我收藏+]

位运算

位运算概述
符号 描述 运算规则
& 两个位都为1时,结果才为1,另外情况下都为0
| 两个位都为0时,结果才为0,另外情况下都为1
^ 异或 两个位相同为0,相异为1
~ 取反 0变1,1变0
<< 左移 各二进制全部左移若干位,高位丢弃,低位补0
>> 右移

各二进制全部右移若干位,对无符号数,高位补0,有符号数,各编译器处理方法不一样,有的补符号位(算数右移),有的补0(逻辑右移)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

这些位运算中我们可以特别注意一下异或操作,因为疑惑操作有以下三个性质:

1.任何数和0做异或运算,结果仍然时原来的数,即:a0=a

2.任何数和其自身做异或运算,结果是0,即:a⊕a=0;

3.异或运算满足交换律和结合率,即:a⊕b⊕a=b⊕a⊕a=b⊕(a⊕a)=b⊕0=b。

利用这些性质,我们可以解决例如“只出现一次的数字”这样的问题:

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,1]
输出: 1
示例 2:

输入: [4,1,2,1,2]
输出: 4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/single-number

int singleNumber(int* nums, int numsSize){
    int ans=0;
    for(int i=0;i<numsSize;i++)
    ans^=nums[i];
    return ans;
}

对于左移操作来说,若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。同理,右移操作,每右移一位,相当于该数除以2。

另外还有一些位操作(https://labuladong.gitbook.io/algo/suan-fa-si-wei-xi-lie/chang-yong-de-wei-cao-zuo):

利用或操作 | 和空格将英文字符转换为小写:

(‘a‘ ‘ ‘) = ‘a‘

(‘A‘ ‘ ‘= ‘a‘

利用与操作 & 和下划线将英文字符转换为大写:

(‘b‘ & ‘_‘) = ‘B‘

(‘B‘ & ‘_‘) = ‘B‘

利用异或操作 ^ 和空格进行英文字符大小写互换:

(‘d‘ ^ ‘ ‘) = ‘D‘

(‘D‘ ^ ‘ ‘) = ‘d‘

判断两个数是否异号:

int x = -1, y = 2;
bool f = ((x ^ y) < 0); // true

int x = 3, y = 2;
bool f = ((x ^ y) < 0); // false

另外一个常用的算法操作:n&(n-1)。它的作用是消除数字n的二进制中的最后一个1。

从上面这个还可以引申出来的问题:

1.计算一个无符号整数的二进制表达式数字位数为1的个数(汉明重量)。

int hammingWeight(int n)
{
     int res=0;
     while(n!=0)
      {
        n=n&(n-1);
         res++;
       }    
    return res;
}        

2.判断一个数是否是2的指数

一个数如果是2的指数,那么它的二进制表示一定只含一个1

bool isPowerOfTwo(int n) {
    if (n <= 0) return false;
    return (n & (n - 1)) == 0;
}

 

 

 

 

 

 

 

 

利用位运算可以解决的一些问题

原文:https://www.cnblogs.com/happy2333/p/12989609.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!