Microsoft Interview Question
Country: United States
You just need 2 lines of code:
unsigned int mask = (((m >> i) ^ (n >> k)) & ( ((1UL <<l) -1) >> (k-1)));
n = n ^ (mask << k);
This is based on the logic of swap using XOR.
if u want to swap a & b using XOR: a = a^b, b=a^b and a = a^b
Just like that, lets assume I want to swap bits of m and n.
((m >> i) ^ (n >> k)) : This is just like first step a^b
((1UL <<l) -1) >> (k-1) : This is 0s followed by 1s of size (l-k+1) Eg: 00000111
This means we are trying to swap bits of length 3 bits.
mask = (((m >> i) ^ (n >> k)) & ( ((1UL <<l) -1) >> (k-1)));
mask will contain 0s followed by XOR of bits of m and n of length l-k+1
n = n^(mask <<k)
This is step 2 of XOR swap that is b = a^ b. In this case a is mask and b is n.
Hope this helps.
@king
But just to add one last line:
m=m^n
to also note the changes in m as said by you which is the last step of swapping
It's not clear if i, j, k, l zero- or one-based. For one-based indexing solution is underneath (and extendable for zero-based). It's also assumed that l-k == j-i
// For Java 7
public class Main {
// src[k..k+len] => dst[i..i+len]
public static int copy(int src, int k, int dst, int i, int len) throws Exception {
if (k < 0 || i < 0 || len <= 0 || i+len > 32 || k+len > 32) {
throw new IllegalArgumentException();
}
//
for (int test = 1 << k, mask = 1 << i; len > 0; len--, test <<= 1, mask <<= 1) {
if ((src & test) > 0) dst |= mask;
else dst &= ~mask;
}
return dst;
}
// n=1010000000,m=10101010,i=3,j=5,k=5,l=7..output=10'101'00000)
public static void main(String[] args) throws Exception {
int n = 0b1010000000;
int m = 0b10101010;
int r = copy(m, 5 + 1, n, 3 + 1, 3);
System.out.println(Integer.toString(r, 2));
}
}
#include <stdio.h>
int length(int x){
int l = 0;
while (1){
x = x / 2;
l++;
if (x == 0){
return l;
}
}
}
int main(){
int i = 3, j = 5, l = 5, k = 7;
int n = (1 << 9) + (1 << 7);
int m = (1 << 1) + (1 << 3) + (1 << 5) + (1 << 7);
int length = length(n);
for (int p = length - j; p <= length - i; p++){
n = n | (1UL << p);
}
m = m << (k - i);
length = length(m);
for (int p = 0; p < length; p++){
if (p < length - k || p > length - l){
m = m | (1UL << p);
}
}
n = n & m;
return 0;
}
#include <stdio.h>
int length(int x){
int l = 0;
while (1){
x = x / 2;
l++;
if (x == 0){
return l;
}
}
}
int main(){
int i = 3, j = 5, l = 5, k = 7;
int n = (1 << 9) + (1 << 7);
int m = (1 << 1) + (1 << 3) + (1 << 5) + (1 << 7);
int length = length(n);
for (int p = length - j; p <= length - i; p++){
n = n | (1UL << p);
}
m = m << (k - i);
length = length(m);
for (int p = 0; p < length; p++){
if (p < length - k || p > length - l){
m = m | (1UL << p);
}
}
n = n & m;
return 0;
}
#include <stdio.h>
int length(int x){
int l = 0;
while (1){
x = x / 2;
l++;
if (x == 0){
return l;
}
}
}
int main(){
int i = 3, j = 5, l = 5, k = 7;
int n = (1 << 9) + (1 << 7);
int m = (1 << 1) + (1 << 3) + (1 << 5) + (1 << 7);
int length = length(n);
for (int p = length - j; p <= length - i; p++){
n = n | (1UL << p);
}
m = m << (k - i);
length = length(m);
for (int p = 0; p < length; p++){
if (p < length - k || p > length - l){
m = m | (1UL << p);
}
}
n = n & m;
return 0;
}
bitwise operations are a good idea, and it should be the fastest. but if you are allowed to use C++ bitset, it's easier (though a little bit slower, and maybe not allowed in an interview :-)
NOTE: In the following solutions, I have changed the index counting from right to left, starting from 0.
/* Q: Two 32-bit integers n and m are given and positions i,j,k,l are given.
Write a method to copy the contents of m from position k to l into n
from position i to j. Example:
-CBA9876543210
------+-+-+---
n = 1010000000, 640(D)
m = 10101010, 170(D)
i = 5,| | | |
j = 7,| | | |
k = 1,| | | |
l = 3 | | | |
| | | |
O = 1010100000, 672(D)
*/
#include <iostream>
#include <bitset>
using namespace std;
// If you have knowledge of bitset, just use it, but it might not be allowed
// in interviews -)
// NOTE: no overflow detection
// assume i <= j, k <= l, j-i == l--k
int MoveBits_BitSet(int n, int m, int i, int j, int k, int l)
{
bitset<32> bsn(n);
bitset<32> bsm(m);
for (int a = i, b = k; a <= j; ++a, ++b)
{
bsn[a] = bsm[b];
}
return (int)bsn.to_ulong();
}
// Interview allowed solutions
// NOTE: no overflow detection
// assume i <= j, k <= l, j-i == l--k
// how about negative numbers? (Not defined)
int MoveBits_BitWise(int n, int m, int i, int j, int k, int l)
{
// Clear bits n[i..j] (to 0)
unsigned x = 1;
x <<= (j-i+1);
x -= 1;
x <<= i;
x = ~x;
x &= n;
// Get bits m[k..l], and move them to the position [i..j]
unsigned y = 1;
y <<= (l+1);
y -= 1;
y &= m;
y >>= k;
y <<= i;
return x | y;
}
int main()
{
int n = 640, m = 170;
int i = 5, j = 7, k = 1, l = 3;
cout << MoveBits_BitSet(n, m, i, j, k, l) << endl;
cout << MoveBits_BitWise(n, m, i, j, k, l) << endl;
}
/* Output:
672
672
*/
let us take m = 3937331622 and n = 3416423919
m binary value is 1110 1010 1010 1110 1110 1001 1010 0110
n binary value is 1100 1011 1010 0010 0111 1101 1110 1111
i = 9, j = 16.....
so we have to pick from the 9th bit to 16th bit of 'n'
ie ..... 1100 1011 <1010 0010> 0111 1101 1110 1111......
k = 15, l = 22;
And we have to pick from the 15th bit to 22nd bit of 'm' for replacement
ie ..... 1110 1010 1010 11<10 1110 10>01 1010 0110
And then we should find the mask for 'n'....
mask is just all bits will be OFF other than 9 to 16th bit...
so we will get....
0000 0000 <1111 1111> 0000 0000 0000 0000
we should find the mask for 'm'....
mask is just all bits will be ON other than 15 to 22nd bit...
so we will get....
1111 1111 1111 11<00 0000 00>11 1111 1111
Now, AND of 'm' and its mask will be 3937141158
ie.... 1110 1010 1010 11<00 0000 00>01 1010 0110 (say "A")
here note that , the bits which need replacement become OFF.
Now, AND of 'n' and its mask will be 10616832
ie.... 0000 0000 <1010 0010> 0000 0000 0000 0000 (say "B")
here note that , the bits which going to replace in 'm' are retained as it is from 'n'.
And, this value obtained needs to be right shifted so that <1010 0010> will get settle in 'm' perfectly.
the number of times we need to do the right shift will be k - i... here 15 - 9 will give you 6... so we have to shift "B" for 6 times
so that you will get a new "B"...... now add(OR) "A" , "B" to get the solution
Here the solution is 3937307046
ie.... 1110 1010 1010 11<10 1000 10>01 1010 0110
thus the bits are replaced!!!
Here is the code....
- FindMind July 17, 2013