给定16位数据,我需要(使用C ++ 11)找到最大化尾随零数的旋转。
e.g。 (为清楚起见,使用8位),
10110001 -> 11011000 so rot=1
10000011 -> 11100000 so rot=2
etc.
显然,它非常容易“蛮力”。它。但我怀疑有一个优雅的解决方案。
答案 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 ++进一步清理它。