位运算

来源:互联网 发布:大数据世界txt全集下载 编辑:程序博客网 时间:2024/06/06 05:34

1.二进制中1的个数
实现一个函数,输入一个整数,输出该数二进制表示中1的个数。
int NumberOf1(int n){
int count=0;
unsigned int flag=1;
while(flag){
if(n&flag)
count++;
flag=flag<<1;
}
return count;
}
2.二进制插入
有两个32位整数n和m,请编写算法将m的二进制数位插入到n的二进制的第j到第i位,其中二进制的位数从低位数到高位且以0开始。
给定两个数int n和int m,同时给定int j和int i,意义如题所述,请返回操作后的数,保证n的第j到第i位均为零,且m的二进制位数小于等于i-j+1。
测试样例:
1024,19,2,6
返回:1100


class BinInsert {
public:
    int binInsert(int n, int m, int j, int i) {
        // m左移j位
        m <<= j;
        return n | m;
    }
};


3.二进制小数
有一个介于0和1之间的实数,类型为double,返回它的二进制表示。如果该数字无法精确地用32位以内的二进制表示,返回“Error”。
给定一个double num,表示0到1的实数,请返回一个string,代表该数的二进制表示或者“Error”。
测试样例:
0.625
返回:0.101


class BinDecimal {
public:
    string printBin(double num) {
        string str("0.");
        double base = 0.5;
        while(num > 0){
            if(num >= base){
                num -= base;
                str += "1";
            }//if
            else{
                str += "0";
            }//else
            base /= 2;
            if(str.size() > 32){
                str = "Error";
                break;
            }//if
        }//while
        return str;
    }
};
4.最接近的数
有一个正整数,请找出其二进制表示中1的个数相同、且大小最接近的那两个数。(一个略大,一个略小)
给定正整数int x,请返回一个vector,代表所求的两个数(小的在前)。保证答案存在。
测试样例:
2
返回:[1,4]
class CloseNumber {
public:
    vector<int> getCloseNumber(int x) {
        // write code here
        vector<int> out;
        out.push_back(findLe(x));
        out.push_back(findGe(x));
        return out;
 
    }
    int findGe(int n){
        unsigned t1 = n&(-n);
        unsigned t2 = n + t1;
        return t2 | ((n^t2) / t1) >> 2;
    }
    int findLe(int n){
        unsigned t1 = (n + 1)&(~n);//最右边的0位置 ;
        if (t1 > 0){
            int t2 = n / t1*t1;//n最右边0右边的1置为0;
            unsigned t3 = t2&(-t2); //t2最右边的1
            unsigned t4 = t3 / (t1<<1);
            unsigned t5 = t2^t3;
            return t5 | ((t3 - 1) / t4*t4);
        }
        else{
            unsigned t1 = n&(-n);//n最右边的1
            return n ^ ((t1 >> 1) | t1);
        }
    }
};
5.整数转化
编写一个函数,确定需要改变几个位,才能将整数A转变成整数B。
给定两个整数int A,int B。请返回需要改变的数位个数。
测试样例:
10,5
返回:4
class Transform {
public: 
int calcCost(int A, int B) {
        // write code here
        int res = A ^ B;
        int count = 0;
        while(res != 0)
        {
          if((res & 1) !=0)
            {
                count++;
            }
            res >>= 1;
        }
        return count;
    }
};
6.奇偶位交换
请编写程序交换一个数的二进制的奇数位和偶数位。(使用越少的指令越好)
给定一个int x,请返回交换后的数int。
测试样例:
10
返回:5
class Exchange {
public:
    int exchangeOddEven(int x) {
        // write code here
        int odd  = ((x&0x55555555)<<1);
        int even = ((x&0xAAAAAAAA)>>1)&0x7fffffff; 
        return even|odd;
    }
};
7.找出缺失的整数
数组A包含了0到n的所有整数,但其中缺失了一个。对于这个问题,我们设定限制,使得一次操作无法取得数组number里某个整数的完整内容。唯一的可用操作是询问数组中第i个元素的二进制的第j位(最低位为第0位),该操作的时间复杂度为常数,请设计算法,在O(n)的时间内找到这个数。
给定一个数组number,即所有剩下的数按从小到大排列的二进制各位的值,如A[0][1]表示剩下的第二个数二进制从低到高的第二位。同时给定一个int n,意义如题。请返回缺失的数。
测试样例:
[[0],[0,1]]
返回:1
题目:
numbers是一个已经排好序的二维数组,存储的是0-n,但是缺少一个数,每一行存储的是每个数的
二进制,从二进制低位开始存储。
目标:求缺少的那个数
思路:整数值x的二进制表示最低位为1的时候,x为奇数;最低位为0时,x为偶数。
由于数组中的数是0~n剩余数按照从小到大进行排列的,因此在缺失数之前,数组行标与数是相等的,即行标i = x,此时行标i % 2的值与数组中numbers[i][0]是相等的,即i为奇数,numbers[i][0]为1;为偶数时,numbers[i][0]为0.
第一个 i % 2与numbers[i][0]不相等处即为缺失数。
要注意缺失数为n即最大值的情况。要单独return n;
代码如下所示:
class Finder {
public:
    int findMissing(vector<vector<int> > numbers, int n) {
        // write code here
        for(int i = 0; i < n; i ++)
            if(i % 2 != numbers[i][0])
            return i;
        return n;
    }
};
8.像素设定
有一个单色屏幕储存在一维数组中,其中数组的每个元素代表连续的8位的像素的值,请实现一个函数,将第x到第y个像素涂上颜色(像素标号从零开始),并尝试尽量使用最快的办法。
给定表示屏幕的数组screen(数组中的每个元素代表连续的8个像素,且从左至右的像素分别对应元素的二进制的从低到高位),以及int x,int y,意义如题意所述,保证输入数据合法。请返回涂色后的新的屏幕数组。
测试样例:
[0,0,0,0,0,0],0,47
返回:[255,255,255,255,255,255]


class Render {
public:
    vector<int> renderPixel(vector<int> screen, int x, int y) {
       int start = x/8;
       int end = y/8;
       int i;
       if(start<end){
           for(i=x%8;i<8;i++)
               screen[start] |= (0x1<<i);
           for(i=start+1;i<end;i++)
               screen[i] |= 0xff;
           for(i=0;i<=y%8;i++)
               screen[end] |= (0x1<<i);
       }else{
           for(i=x%8;i<=y%8;i++)
               screen[start] |= (0x1<<i);
       }
       return screen;
   }
};


0 0