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

时间:2016-01-31 21:47:05

标签: c++ c++11 rotation bit-manipulation

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

e.g。 (为清楚起见,使用8位),

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

显然,它非常容易“蛮力”。它。但我怀疑有一个优雅的解决方案。

3 个答案:

答案 0 :(得分:1)

我认为代码中的一切都很清楚。通过类比向左移动。您可以在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;
}

答案 1 :(得分:1)

以下函数产生左旋转距离(因为您可能希望之后使用std :: rotate)。想法:当你偶然发现0时,通过这些位,从那里算出零。使用modulo环绕结束并继续计数:

#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;
}

答案 2 :(得分:0)

这是一个优雅的解决方案&#39;想法我在考虑: 假设我们正在测试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 ++进一步清理它。