位运算相关题目

位运算符

  • 与&
  • 或|
  • 异或^
  • 左移运算符m<<n:左移n位,最左边的n位将被丢弃,同时在右边补n个0
    例如:00001010<<2=00101000
  • 右移运算符:m>>n:右移n位,最右边的n位将被丢弃。但是左边补齐的时候分两种情况:如果是一个无符号数值,补0;如果是一个有符号数值,用符号位去补,即正数补0,负数补1
    例如:有符号数00001010>>2=00000010
    有符号数10001010>>3=11110001

相关题目:

1.二进制中1的个数

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

方法一:

最常想到的方法但是可能引起死循环
判断整数最右边一位是不是1,然后不断地右移判断倒数第二位,判断方法是通过与1做&

class Solution {
public:
     int  NumberOf1(int n) {
         int count=0;
         while(n)
         {
             if(n&1)
                 count++;
             n=n>>1;
         }
         return count;
     }
};

但是如果输入一个负数,右移时会在左边补1,一直右移会引起死循环

方法二:

首先把n和1做与运算,判断n的最低位是不是1,接着把1左移一位得到2,再与n做与运算,判断n的次低位是不是1

class Solution {
public:
     int  NumberOf1(int n) {
         int count=0;
         unsigned int flag=1;
         while(flag)
         {
             if(n&flag)
                 count++;
             flag=flag<<1;
         }
         return count;
     }
};

循环的次数等于整数二进制的位数,32位的整数就需要循环32次

方法三:

整数中有几个1就需要循环几次
把一个整数减去1,再和原整数做与运算,就会把该整数最右边的1变成0,那么一个整数的二进制表示中有多少个1就可以进行多少次这样的操作。
例如1100,减去1得到1011,做与得到1000
1000再减去1得到0111,做与得到0000

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

2.用一条语句判断一个整数是不是2的整数次方

一个整数如果是2的整数次方,那么它的二进制表示中有且只有一位是1,而其他所有位都是0。把这个整数减去1之后再和它自己做与运算,这个整数中唯一的1就会变成0.

#include<iostream>
using namespace std;

int main()
{
	int n;
	cin>>n;
	if(((n-1)&n)==0)
		cout<<"true";
	else
		cout<<"false";
	return 0;	
}

3.不用加减乘除做加法

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

class Solution {
public:
    int Add(int num1, int num2)
    {
        int sum=0,carry=0;
        while(num2)
        {
            sum=num1^num2;
            carry=(num1&num2)<<1;
            num1=sum;
            num2=carry;
        }
        return num1;;
    }
};

4.不使用新的变量,交换两个变量的值

基于加减法
a=a+b;
b=a-b;
a=a-b;
基于异或:
a=a^b;
b=a^b;
a=a^b;

5.比特位计数

给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。
示例 1:
输入: 2
输出: [0,1,1]
示例 2:
输入: 5
输出: [0,1,1,2,1,2]

class Solution {
public:
    vector<int> countBits(int num) {
        vector<int> res(num+1,0);
        for(int i=1;i<=num;i++)
        {
            res[i]=res[i&(i-1)]+1;
        }
        return res;
        
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值