旋转整数以获得最大尾随二进制零

Rotate integer for maximum trailing binary zeros

给定 16 位数据,我需要(使用 C++11)找到使尾随零数最大化的旋转。

例如(为清楚起见,使用 8 位),

10110001 -> 11011000 so rot=1
10000011 -> 11100000 so rot=2
etc.

显然 'brute force' 它很容易。但我怀疑有一个优雅的解决方案。

我认为代码中的一切都清楚了。类推左移。您可以在 cpp.sh

上进行测试
#include <iostream>
#include <string>
#include <bitset>

const int count_bits = 8;

int num_right_rotation(std::string number)
{
    int max = 0;
    int rotation = 0;
    std::bitset<count_bits> one (number);
    for(int i=0; i<count_bits; i++)
    {
        int max_temp = 0;
        for(int j=0; j<count_bits; j++)
        {
            if(!one[j]) max_temp++;
            else break;
        }

        if(max_temp > max)
        {
            max = max_temp;
            rotation = i;
        }
        one = (one>>1) | (one<<count_bits-1);
    }
    return rotation;
}

int main()
{
    std::cout << num_right_rotation ("10110001") << std::endl;
    std::cout << num_right_rotation ("10000011") << std::endl;

    return 0;
}

以下函数产生左旋转距离(因为您可能想在之后使用 std::rotate)。想法:遍历这些位,当您偶然发现一个 0 时,从那里开始计算零。用取模绕到最后继续数:

#include <algorithm>
#include <iostream>
#include <string>

int rotation(std::string bits)
{
  int max_pos = 0;
  int max_count = 0;
  for (int i = 0; i < bits.size();)
  {
    if (bits[i] == '0')
    {
      int count = 1;
      for (; bits[(i + count) % bits.size()] == '0' && count < bits.size(); 
             ++count);
      if (count > max_count)
      {
        max_pos = i;
        max_count = count;
      }
      i += count;
    }
    else
    {
      ++i;
    }
  }

  return (max_pos + max_count) % bits.size();
}

int main()
{
  std::cout << rotation ("10110001") << std::endl;
  std::cout << rotation ("10000011") << std::endl;

  return 0;
}

这是我正在考虑的 'elegant solution' 想法: 假设我们正在测试 x = 1110 0000.
减去 1 得到 11011 1111。 而 x^(x-1) = 0011 0000.

即我们总是会得到这种形式的数字,具体取决于尾随零的数量。

最尾随的零将产生最大的数字。

所以 Pythonesque 伪代码可能看起来像:

iWinner = [x ^ (x-1) where x=rot(X,i) for i in range(16)].indexWithMaxValue()

在 C:

uint16_t x = 42;
uint16_t xWinner=0;
for(uint16_t i=0,yMax=0; i<16; i++) {
    x = x << 1 + x >> 15; // rotate 1 left
    uint16_t y = x ^ (x-1);
    if( y > yMax ) {
        yMax = y;
        xWinner = x;
    }
}

不过,我看不到任何利用 C++ 进一步清理它的方法。