Given a positive integer, print the next smallest and the next largest number that have the same number of 1 bits in their binary representation.
unsigned int checkOnes(int num)
{
int count = 0;
while(num > 0)
{
if(num % 2 == 1)
count++;
num = num >> 1;
}
return count;
}
unsigned int getNextSmallest_BruteForce(unsigned int num)
{
int originalOnes = checkOnes(num);
while(num >0)
{
if( originalOnes == checkOnes(++num))
break;
}
return num;
}
unsigned int getNextLargest_BruteForce(unsigned int num)
{
int originalOnes = checkOnes(num);
while(num >0)
{
if( originalOnes == checkOnes(--num))
break;
}
return num;
}
unsigned int getNextLargest(unsigned int num)
{
//Find first 0
int firstZero = 0;
int count1 = 0;
int count0 = 0;
unsigned int tmp = num;
while(tmp > 0)
{
if(tmp % 2 == 0)
{
count0++;
break;
}
else
{
count1++;
firstZero++;
tmp = tmp >> 1;
}
}
tmp = tmp >> 1;
int oneNextFirstZero = firstZero+1;
while(tmp > 0)
{
if(tmp % 2 == 1)
{
count1++;
break;
}
else
{
count0++;
oneNextFirstZero++;
tmp = tmp >> 1;
}
}
//Set 0s from 0~oneNextFirstZero
num = (num >> (oneNextFirstZero+1))<<(oneNextFirstZero+1);
count0--; //bit oneNextFirstZero has been set to 0;
unsigned int allOnes = ~0;
allOnes = ~(allOnes << count1);
allOnes <<= count0;
return num | allOnes;
}
unsigned int getNextSmallest(unsigned int num)
{
//Find first 1
int firstOne = 0;
int count1 = 0;
int count0 = 0;
unsigned int tmp = num;
while(tmp > 0)
{
if(tmp % 2 == 1)
{
count1++;
break;
}
else
{
count0++;
firstOne++;
tmp = tmp >> 1;
}
}
tmp = tmp >> 1;
int zeroNextFirstOne = firstOne + 1;
while(tmp > 0)
{
if(tmp % 2 == 0)
{
count0++;
break;
}
else
{
zeroNextFirstOne++;
count1++;
tmp = tmp >> 1;
}
}
if( (count1 + count0) == 32 || (count0+count1) == 0)
return -1;
//Set zeroNextFirstOne to 1
num = (1<<zeroNextFirstOne) | num;
num = (num >> (count0 + count1 -1 )) << (count0 + count1 -1);
unsigned int mask;
//One 1 has been set, thus count1-1
mask = (1 << (count1-1)) -1;
return num | mask;
}