Amazon Interview Question
Software Engineer / DevelopersHey John..
I doubt the solution given by you to be bit wise reversal instead of the byte wise reversal..
void byteRev(int num)
{
int a1=num&(0xF<<24);
int a2=num&(0xF<<16);
int a3=num&(0xf<<8);
int a4=num&0xF;
return (a1>>24)|(a2>>8)|(a3<<8)|(a4<<24);
}
Create a "union" consisting of -
- 4 char variables (or just one array of 4 char) and
- one int. (I assumed one int is 4 bytes, unix style, and not 2 bytes, windows style)
Now store a value into union.int variable; access it 'backwards' using the 4 char variable and save back to int, like this -
int tmp = union.char[3]*1000 + union.char[2]*100 + union.char[1]*10 + union.char[0]
union.int = tmp;
print union.int.
Above syntax is of course symbolic and not strictly C.
Say what?
One more solution for 32 bit num with O(1) complexity.
int BitRev(unsigned int num)
{
return ( ((num & (1 << 31)) >> 31)
| ((num & (1 << 30)) >> 29)
| ((num & (1 << 29)) >> 27)
| ((num & (1 << 28)) >> 25)
| ((num & (1 << 27)) >> 23)
| ((num & (1 << 26)) >> 21)
| ((num & (1 << 25)) >> 19)
| ((num & (1 << 24)) >> 17)
| ((num & (1 << 23)) >> 15)
| ((num & (1 << 22)) >> 13)
| ((num & (1 << 21)) >> 11)
| ((num & (1 << 20)) >> 9)
| ((num & (1 << 19)) >> 7)
| ((num & (1 << 18)) >> 5)
| ((num & (1 << 17)) >> 3)
| ((num & (1 << 16)) >> 1)
| ((num & (1 << 15)) << 1)
| ((num & (1 << 14)) << 3)
| ((num & (1 << 13)) << 5)
| ((num & (1 << 12)) << 7)
| ((num & (1 << 11)) << 9)
| ((num & (1 << 10)) << 11)
| ((num & (1 << 9)) << 13)
| ((num & (1 << 8)) << 15)
| ((num & (1 << 7)) << 17)
| ((num & (1 << 6)) << 19)
| ((num & (1 << 5)) << 21)
| ((num & (1 << 4)) << 23)
| ((num & (1 << 3)) << 25)
| ((num & (1 << 2)) << 27)
| ((num & (1 << 1)) << 29)
| ((num & (1 << 0)) << 31)
);
}
This can be done using recursion. Basically Merge Sort approach. Once you know the size of int you know how many bytes are there. Lets assume we have 32 bit int so 4 bytes. Divide in two parts lets say A and B. Move bits in A to right by size of A places and similarly move the bits in B to the left. Further divide A into 2 parts if possible and then again apply the same procedure. Now as you return start merging A and B by simply doing an OR. Little complex to write but I guess this could serve as a generic solution. Will try to post code sometime soon.
Code for the anonymous sol,
eg: 10010101 o/p => 10101001
//initially S = (SizeOfTheInteger/2)
//T = SizeOfTheInteger
reverse(val , T , S)
{
leftVal = val >> S; //rightshift
rightVal = val << (T-S); //left shift
rightVal = val >> (T-S); //again right shift
if(right shifting of leftVal once doensn't make leftVal == 0)
leftVal = reverse(leftVal);
if(left shifting of rightVal once doesn't make rightVal == 0)
rightVal = reverse(rightVal);
rightVal = rightVal<<S;
return (leftVal | rightVal);
}
you all are right :)
but this is in words
1byte = 8 bits (genius me...)
eg. 1011 now what you all do to get last 2 bits ?? divide by 2^(bits you want)
here 4 ... got 10 as quotient 11 as remainder
now 11<<(bits you want ) | quotient == 1100|10 = 1110
EXPAND FOR 8 BITS
i=2^8;
j=8;
fine=0;
while(num > 0)
{
rem=num%i;
fine = fine<<j||rem
num=num/i;
}
- john June 07, 2009