Find next number with specific hamming weight

只谈情不闲聊 提交于 2019-12-02 03:39:54

问题


Given a certain integer x, I wish to compute the next higher integer y which has a certain hamming weight w. Mind that the hamming weight of x does not have to be w as well.

So, for example x = 10 (1010) and w = 4 the result should be y = 15 (1111).

Obviously, I could achieve this by just incrementing x but that would be a very slow solution for high numbers. Can I achieve this by the means of bit shifts somehow?


回答1:


There are three cases: the Hamming weight (a.k.a. bitwise population count) is reduced, unchanged, or increased.

Increased Hamming weight

Set enough successive low-order 0-bits to achieve the desired weight.

This works because each successive low-order bit is the smallest value that you can add, and their sum is the smallest difference that will sufficiently increase the Hamming weight.

Unchanged Hamming weight

  1. Add the value of the lowest-order 1-bit.
  2. Increase the Hamming weight per above, if necessary.

This works because the value of the lowest set bit is the lowest value that will cause a carry to occur. Adding any lower bit-value would simply set that bit, and increase the Hamming weight.

As long as addition "carries a one," bits will be cleared. The resulting weight must be the equal or reduced. If several bits are cleared due to a chain of carries, you'll need to increase the weight in compensation by setting low-order bits.

Reduced Hamming weight

  1. Clear enough low-order 1-bits to achieve the new desired weight.
  2. Follow the above process for unchanged weight.

This works because clearing low-order 1-bits finds the preceding number with the desired weight, by subtracting the smallest viable amount. From the preceding number of the correct weight, follow the "unchanged weight" algorithm to reach the next number.



来源:https://stackoverflow.com/questions/31357124/find-next-number-with-specific-hamming-weight

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!