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;
}
};
实现一个函数,输入一个整数,输出该数二进制表示中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;
}
};