我正在寻找一种简洁的方法来列出(8位)整数,其二进制表示与另一个整数相同,直到旋转和反射。
例如,列表可能以as开头
0
1
(2 =跳过10b,因为你可以将位旋转为1,因此跳过所有2的幂。除了0之外的每个数字都是奇数)
3 = 11b时
5 = 101B
7 = 111B
9 = 1001B
11 = 1011b(因此13 = 1101b将被跳过,因为11010000b是1101b的反射,然后可以向右旋转4次)
。
。
。
理想情况下,如何将其推广到具有不同位数(16,32或仅 n )的数字以及除2之外的其他基数。
答案 0 :(得分:1)
由于@John Smith认为我的评论很好,所以这是一个答案。
The answers here可能很有启发性。
答案 1 :(得分:0)
感谢Jeffromi更好地解释了这个问题 - 我删除了之前的答案。
这是Perl的另一个解决方案。 Perl是解决这类问题的好语言,因为它可以很容易地将数字视为文本,将文本视为数字。
i: for $i (0..255) {
$n1 = sprintf "%08b", $i; # binary representation of $i
$n2 = $n1; # "unreflected" copy of $n1
$n3 = reverse $n1; # "reflection" of $n1
for $j (1..8) {
$n2 = chop($n2) . $n2; # "rotate" $n2
$n3 = chop($n3) . $n3; # "rotate" $n3
next i if $found{$n2} or $found{$n3};
}
# if we get here, we rotated $n2 and $n3 8 times
# and didn't get a nonsymmetric byte that we've
# seen before -- this is a nonsymmetric byte
$found{$n1}++;
print "$i $n1\n";
}
这不像以前的解决方案那么简单,但是jist将尝试所有16种组合(2次反射x 8次旋转)并将它们与您之前看到的所有非对称字节进行比较。
在Perl中有一个用于旋转位移的运算符,但我使用的chop($num) . $num
惯用语更好地概括了 n 的基本问题。
答案 2 :(得分:0)
您可以使用类似于Eratosthenes筛子的筛子作为素数。
在Java中使用位数组(BitSet
),每个数字都有一位。
最初标记所有位。
顺序遍历位数组,直到找到在索引n
设置的下一位,这是您集合中的数字。然后清除可以通过旋转和镜像从n
到达的所有其他数字的位。
在今天的机器上,这是可行的,最多32位,这将使用512MB的内存。
答案 3 :(得分:0)
Eratosthenes'Sieve的另一种解决方案是构建一个测试T(k),对任何给定的k都返回True或False。
速度会慢一些,但这样就不需要存储空间,因此可以更容易地扩展到任意数据长度。
如果你暂时解决问题,并说我们只是想放弃反射,那么这很容易:
T_ref(k) returns true iff k <= Reflection(k).
至于旋转位,可以完全相同:
T_rot(k) returns true iff k == MIN{the set of all rotations of k}
你可以考虑将你的整数划分为一堆等价类E(k),其中E(k)是k的所有反射和旋转排列的集合。
您可能需要花一点时间来确定自然数字N的集合很容易分成这些不相交的子集。
然后设置
{k s.t. k == MIN(E(k)) }
将保证每个等价类中只包含一个元素。
这会成为一个非常好的面试问题。