Calculating the next higher number which has same number of set bits?

后端 未结 3 449
不思量自难忘°
不思量自难忘° 2021-01-17 06:35

A solution is given to this question on geeksforgeeks website.

I wish to know does there exist a better and a simpler solution? This is a bit complicated to understa

3条回答
  •  逝去的感伤
    2021-01-17 07:13

    I am pretty sure this algorithm is as efficient and easier to understand than your linked algorithm.

    The strategy here is to understand that the only way to make a number bigger without increasing its number of 1's is to carry a 1, but if you carry multiple 1's then you must add them back in.

    • Given a number 1001 1100

    • Right shift it until the value is odd, 0010 0111. Remember the number of shifts: shifts = 2;

    • Right shift it until the value is even, 0000 0100. Remember the number of shifts performed and bits consumed. shifts += 3; bits = 3;

    • So far, we have taken 5 shifts and 3 bits from the algorithm to carry the lowest digit possible. Now we pay it back.

    • Make the rightmost bit 1. 0000 0101. We now owe it 2 bits. bits -= 1

    • Shift left 3 times to add the 0's. 0010 1000. We do it three times because shifts - bits == 3 shifts -= 3

    • Now we owe the number two bits and two shifts. So shift it left twice, setting the leftmost bit to 1 each time. 1010 0011. We've paid back all the bits and all the shifts. bits -= 2; shifts -= 2; bits == 0; shifts == 0

    Here's a few other examples... each step is shown as current_val, shifts_owed, bits_owed

    0000 0110
    0000 0110, 0, 0 # Start
    0000 0011, 1, 0 # Shift right till odd
    0000 0000, 3, 2 # Shift right till even
    0000 0001, 3, 1 # Set LSB
    0000 0100, 1, 1 # Shift left 0's
    0000 1001, 0, 0 # Shift left 1's
    

    0011 0011
    0011 0011, 0, 0 # Start
    0011 0011, 0, 0 # Shift right till odd
    0000 1100, 2, 2 # Shift right till even
    0000 1101, 2, 1 # Set LSB
    0001 1010, 1, 1 # Shift left 0's
    0011 0101, 0, 0 # Shift left 1's
    

提交回复
热议问题