【问题标题】:How to convert an integer into a Binary Array..如何将整数转换为二进制数组..
【发布时间】:2012-07-09 05:22:54
【问题描述】:

谁能给出最简单的解决方案,将整数转换为表示其相关二进制数字的整数数组..

Input  => Output
1      => [1]
2      => [2]
3      => [2,1]
4      => [4]
5      => [4,1]
6      => [4,2]

One way is :
Step 1 : 9.to_s(2) #=> "1001"
Step 2 : loop with the count of digit
         use / and % 
         based on loop index, multiply with 2
         store in a array

还有其他直接或更好的解决方案吗?

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    Fixnum 和 Bignum 有一个 [] 方法,它返回第 n 位的值。有了这个我们可以做

    def binary n
      Math.log2(n).floor.downto(0).select {|i| n[i] == 1 }.collect {|i| 2**i}
    end
    

    您可以通过计算 2 的连续幂直到该幂太大来避免调用 Math.log2:

    def binary n
      bit = 0
      two_to_the_bit = 1
      result = []
      while two_to_the_bit <= n
        if n[bit] == 1
          result.unshift two_to_the_bit
        end
        two_to_the_bit = two_to_the_bit << 1
        bit += 1
      end
      result
    end
    

    更详细,但更快

    【讨论】:

    • 不错。好的,现在我确信升级到 Ruby 1.9。我想要我的 log2。
    • +1 ... 但是:为了完整性,不要忘记过滤掉零:)
    • 糟糕,忘记了零。
    【解决方案2】:

    这是一个使用 Ruby 1.8 的解决方案。 (Math.log2 是在 Ruby 1.9 中添加的):

    def binary(n)
      n.to_s(2).reverse.chars.each_with_index.map {|c,i| 2 ** i if c.to_i == 1}.compact
    end
    

    在行动:

    >>  def binary(n)
    >>       n.to_s(2).reverse.chars.each_with_index.map {|c,i| 2 ** i if c.to_i == 1}.compact
    >>     end
    => nil
    >> binary(19)
    => [1, 2, 16]
    >> binary(24)
    => [8, 16]
    >> binary(257)
    => [1, 256]
    >> binary(1000)
    => [8, 32, 64, 128, 256, 512]
    >> binary(1)
    => [1]
    

    当然,如果您希望按降序查看值,请添加最后一个 .reverse

    【讨论】:

    • 感谢 Ray...Yossi 建议 -> tap[] .. array = [].tap{|arr| n.to_s(2).reverse.chars.each_with_index {|c,i| arr
    • @Ray:是的,最后一个是好的(除了最后一个反向丢失?)。不确定我们是否需要查看尝试 ;-)
    • 你说得对@tokland,尝试很愚蠢。现在清理了。
    【解决方案3】:
    class Integer
      def to_bit_array
        Array.new(size) { |index| self[index] }.reverse!
      end
    
      def bits
        to_bit_array.drop_while &:zero?
      end
    
      def significant_binary_digits
        bits = self.bits
        bits.each_with_object(bits.count).with_index.map do |(bit, count), index|
          bit * 2 ** (count - index - 1)
        end.delete_if &:zero?
      end
    end
    

    改编自 these solutions found in comp.lang.ruby 并对其进行了改进。

    一些简单的基准测试表明this solution 比涉及base-2 logarithmsstring manipulation 的算法快,但比direct bit manipulation 慢。

    【讨论】:

    • log2 版本对我来说更快。我认为这将取决于您使用它的值有多大:生成了多少“浪费”位(这也取决于 32 与 64 位 ruby​​)
    • @Frederick,很好的观察。根据 Ideone 的计时器,您的新算法确实击败了我的算法。
    猜你喜欢
    • 2019-03-29
    • 2020-12-05
    • 2013-09-09
    • 1970-01-01
    • 2012-04-10
    • 1970-01-01
    • 2013-11-05
    • 2012-05-02
    • 2016-07-08
    相关资源
    最近更新 更多