Thursday 6 June 2013

Given a number print the next largest number and just smallest number that have same number of 1's in binary representation.

   /*
        NEXT GREATER NUMBER
        -------------------
        1. Scan number from right to left bits.
        2. As soon as first 1 bit is encountered set the encounterFlag.
        3. If encounterFlag is set Turn on the first 0 bit.
        4. Turn off the 1 bit on right of above bit.
        5. Make this as small as possible to get just next larger number, Push all 1's after this bit to right end.
       
        NEXT SMALLER NUMBER
        -------------------
        1. Scan number from right to left bits.
        2. As soon as first 0 bit is encountered set the encounterFlag.
        3. If encounterFlag is set Turn off the first 1 bit.
        4. Turn on the 0 bit on right of above bit.
        5. Make this as large as possible to get just previous smaller number, Push all 1's after this bit to as much left as possible.
    */
    #include <iostream>
    using namespace std;
   
    //check if bit at pos is 1 or 0
    bool isSet(int number , int pos)
    {
         if( (number & (1<<pos)) > 0)
             return true;
         return false;
    }
   
    //set Bit at index pos to 1
    int setBit(int number , int pos)
    {
        number |= 1<<pos;
        return number;
    }
   
    //set bit at index pos to 0
    int unsetBit(int number, int pos)
    {
        number &= ~(1<<pos);
        return number;
    }
   
    //Return Next Greater number
    int getNextGreater(int number)
    {
        if(number <= 0)
            return -1;
        int maxIndex;
        int countOnes = 0;
        int pos = 0;
       
        //Scan number from right to left bit.
        for(bool encounterFlag = false; pos < 32 ; pos++)
        {
                if(encounterFlag)
                {
                     if( !isSet(number , pos) )
                     {
                         // set first 0 bit after encounteredFlag is true 
                         number = setBit(number, pos);
                         // unset 1 bit immediately right of the above bit. 
                         number = unsetBit(number, --pos);
                         break;
                     }
                     else
                         continue;
                }
                     //As soon as a 1 is encountered, encounteredFlag is set.
                if( isSet(number , pos))
                     encounterFlag = true;
        }
       
        //Count no. of 1's after maxIndex.
        for(int i=pos -1; i>=0 ; i--)
        {
                if(isSet(number, i))
                    countOnes++;
        }
        //Pushing all 1's to left.
        for(int j=pos -1; j>= countOnes; j--)
            number = unsetBit(number, j);
       
        for(int k=countOnes-1 ; k>=0; k--)
            number = setBit(number, k);
       
        return number;
    }
   
    int getNextSmaller(int number)
    {
        if(number < 0)
            return -1;
        int maxIndex;
        int countOnes = 0;
        int pos = 0;
        for(bool encounterFlag = false; pos < 32; pos++)
        {
             if(encounterFlag)
             {
                  if(isSet(number, pos))
                  {
                      //After encounterFlag is set Turnoff next 1 Bit.
                      number = unsetBit(number, pos);
                      //Turn on 0 bit on right of this bit.
                      number = setBit(number, --pos);
                      break;
                  }
                  else
                      continue;
             }
             //Set encounter flag after first zero is encountered.
             if(!isSet(number,pos))
             {
                  encounterFlag = true;
             }
            
        }
       
        //Count no. of 1's after maxIndex.
        for(int i=pos -1; i>=0 ; i--)
        {
             if(isSet(number, i))
                 countOnes++;
        }
      
        //Pushing all 1's to left.
        for(int j=pos -1; j>= countOnes; j--)
            number = setBit(number, j);
       
        for(int k=countOnes-1 ; k>=0; k--)
            number = unsetBit(number, k);
       
        return number;
       
    }
   
    int main()
    {
        cout<<getNextGreater(18)<<endl;
        cout<<getNextSmaller(18)<<endl;
        system("pause");
    }

1 comment:

  1. Try running:
    cout<<getNextGreater(0)<<endl;
    cout<<getNextSmaller(0)<<endl;

    The result in the both cases is -1

    ReplyDelete