【问题标题】:Count non-symmetric bytes计算非对称字节
【发布时间】:2010-11-07 22:51:37
【问题描述】:

我正在寻找一种简洁的方法来列出(8 位)整数,其二进制表示与另一个整数不同,直到旋转和反射。

例如,列表可能会以
开头 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 之外的其他基数。

【问题讨论】:

  • 我假设 0000 0011 被认为是 1000 0001 的旋转
  • 这里的答案:stackoverflow.com/questions/262826/… 可能很有启发性。
  • @高性能标记。到目前为止,您的答案是最好的。
  • 我遇到的是项链问题。我只是不知道名字。我所要求的(有些人错过了)是一种列举所有项链的干净、优雅的方法。临时做这件事并不难,但分析或概括就更难了。

标签: language-agnostic math binary bit-manipulation


【解决方案1】:

因为@John Smith 认为我的评论是一个很好的答案,所以这是一个答案。

The answers here 可能很有启发性。

【讨论】:

    【解决方案2】:

    感谢 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";
    }
    

    这并不像之前的解决方案那么简单,但主要是尝试所有 16 种组合(2 次反射 x 8 次旋转)并将它们与您之前看到的所有非对称字节进行比较。

    在 Perl 中有一个用于移位移位的运算符,但我使用的 chop($num) . $num 成语更好地概括了基础 n 的问题。

    【讨论】:

      【解决方案3】:

      您可以使用筛子,类似于 Eratosthenes 的筛子来筛选素数。

      使用位数组(Java 中为BitSet),每个数字一位。

      最初标记所有位。

      依次遍历位数组,直到找到设置在索引n 处的下一个位,这是您的集合中的一个数字。然后通过旋转和镜像清除从n 可以到达的所有其他数字的位。

      在今天的机器上,最高 32 位是可行的,这将使用 512MB 的内存。

      【讨论】:

        【解决方案4】:

        Eratosthenes 筛法的另一种解决方案是构建一个测试 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)) } 
        

        将保证只包含每个等价类中的一个元素。

        这将是一个非常好的面试问题。

        【讨论】:

        • iff 是“当且仅当”的数学语言;英石。是“这样”的数学语言
        猜你喜欢
        • 2014-12-10
        • 1970-01-01
        • 2018-06-22
        • 2023-03-08
        • 2019-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多