题目翻译和代码有不正确的地方欢迎批评指正.有好的方法欢迎交流。
第一题:
You are given two 32-bit numbers, N and M, and two bit positions, i and j. Write a method to set all bits between i and j in N equal to M (e.g., M becomes a substring of N located at i and starting at j).
EXAMPLE:
Input: N = 10000000000, M = 10101, i = 2, j = 6
Output: N = 10001010100
把N从左边数的第i到j位设置成M的值
代码如下:
#include<stdio.h>
int main()
{
int N, M;
int i, j;
int x = 0;
scanf("%d %d", &N, &M);
scanf("%d %d", &i, &j);
x = (0|M)<<i; //000M00
N &= (((~0) << (j-i+1)) <<i) | (~((~0)<<i)); //N000N
N |= x;
printf("%d %d", N, M);
}
第二题:
Given a (decimal - e.g. 3.72) number that is passed in as a string, print the binary representation. If the number can not be represented accurately in binary, print “ERROR”
还不知道怎么写代码。
第三题:
Given an integer, print the next smallest and next largest number that have the same number of 1 bits in their binary representation.
给你一个整数n,求出最小的比n大并且和n的二进制中1的个数一样多的数。找出最大的比n小并且和n含的1一样多的数。
方法一:
从n开始依次递增,递减,找到满足条件的数。
方法二:
寻找大数:
1.从n的二进制数的右边往左寻找到第一位是1,并且该位左边的一位是0
2.把找到的这一位变为0,左边的变为1;
3.把变为0的那一位右边的1全部移到最右边(最低位)
寻找小数原理相似。
代码如下:
#include<stdio.h>
int Findlarge(int);
int Findsmall(int);
int main()
{
int n;
int small = 0, large = 0;
scanf("%d", &n);
assert(n >1)
large = Findlarge(n);
small = Findsmall(n);
printf("%d %d", large, small);
}
int Findlarge(int n)
{
int k, count;
k = 1;
count = 0;
while((n & k) == 0)//跳过开始的0
{
k<<= 1;
}
while((n&k)!= 0)//寻找位的值为1,但是右边的位为0 的位
{
k<<= 1;
count++;
}
n |= k;//
k >>= 1;
n&= ~k;
count--; //右边1的个数,
while(k > 0)
{
if((n &k)!= 0)
n &= ~k;
k >>= 1;
}
n |= ~((~0)<<count);
return n;
}
int Findsmall(int n)
{
int k, count;
k = 1;
count = 0;
while((n&k) != 0)
{
k<<= 1;
count++;
}
while((n&k) == 0)
{
k<<= 1;
}
n &= ~k;
k >>= 1;
n |= k;
while(k > 0)
{
k >>= 1;
if(count > 0)
n |= k;
else
{
n &= ~k;
}
count--;
}
return n;
}
第四题:
Explain what the following code does: ((n & (n-1)) == 0).
用来判断n的二进制中是不是只含有一个1,
第五题:
Write a function to determine the number of bits required to convert integer A to integer B.
Input: 31, 14
Output: 2
其实也就是判断两个数,有多少位不同。
用上一题的结论。
代码如下:
#include<stdio.h>
int main()
{
int n, m;
int count;
scanf("%d %d", &n, &m);
m ^= n;
count = 0;
while(m)
{
count++;
m &= m-1;
}
printf("%d\n", count);
}
第六题:
Write a program to swap odd and even bits in an integer with as few instructions as possible (e.g., bit 0 and bit 1 are swapped, bit 2 and bit 3 are swapped, etc).
交换一个数字的奇数位和偶数位.
代码如下:
#include<stdio.h>
int main()
{
int x;
scanf("%d", &x);
x = ((x& 0xaaaaaaaa)>>1) | ((x&0x55555555)<<1);
printf("%d", x);
}
第七题:
An array A[1... n] contains all the integers from 0 to n except for one number which is missing. In this problem, we cannot access an entire integer in A with a single operation. The elements of A are represented in binary, and the only operation we can use to access them is “fetch the jth bit of A[i]”, which takes constant time. Write code to find the missing integer. Can you do it in O(n) time?
题意如下:
给你一个数组A[n],里面存储了0到n的n个数字,你不能获得数组的数字,只能知道数组中数字的第k位是1还是0,你能在o(N)的时间里找到不在数组中的那个数字吗?
思路如下:
先求出n的有效位数,假如为k位,创建一个一个大小为2^k+1次方大小的数组,复制A[n]中的元素到这个数组中,后面的元素从n依次加1;
然后统计每个位上面1和0的个数,就可以知道要找的数字的每一位是0还是1.
假如n=4,扩充到7,使每一位上面的0和1的个数想同。
0000
0001
0010
0011
0100
0101
0110
0111
代码如下:
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
void Find(int* ,int , int , int *);
int GetBitof1(int *, int , int);//获得第k位0或者1的个数
int main()
{
int *A, n;
int i;
int result = 0;
int m = 1;
int count = 0;
int temp;
scanf("%d", &n);
assert(n > 0);
temp = n;
while(temp)//统计n的有效位
{
temp >>= 1;
count++;
}
//count++;
m <<= count;
A = (int *)malloc(sizeof(int) * (m-1));
assert(A != NULL);
printf("Input the value form 0~n\n");
for(i = 0;i < n; ++i)
scanf("%d", A+i);
for(; i < m-1; ++i)//扩充数组,使第k位上面1和0的个数相同
A[i] = i+1;
for(i = 0; i < m-1; ++i)//观察结果
printf("%d ", A[i]);
printf("\n");
Find(A, m-1, 1, &result);
printf("%d ", result);
free(A);
return 0;
}
void Find(int *A, int n, int k, int *result)
{
int m = 1;
int count1 = 0;
int count0 = 0;
m <<= k-1;
if(m > n)
return;
count1 = GetBitof1(A, n, k);
count0 = n-count1;
if(count0 > count1)//0比1多,说明这一位应该是1
{
*result |= m;
// Find(A, n, k+1, result);
}
Find(A, n, k+1, result);
}
int GetBitof1(int *A, int n, int k)
{
int count = 0;
int i;
int value = 1;
value <<= k-1;
for(i = 0; i < n; ++i)
{
if(A[i] &value)
count++;
}
return count;
}