Ruby 将整数转换为二进制,再转换为设置位的整数数组

Ruby Convert integer to binary to integer array of set bits

假设我有一个整数 98。 此字符串的二进制表示形式为:

(98).to_s(2) # 1100010

现在我想将这个二进制字符串转换为所有已设置位的整数数组。这会给我:

[64,32,2]

我该怎么做?

更新: int 到int array 的转换不一定需要涉及String,我知道的就这些。我假设非字符串操作也会更快。

Ruby is amazing seeing all these different ways to handle this!

这里有几种方法:

#1

s = (98).to_s(2)
sz = s.size-1
s.each_char.with_index.with_object([]) { |(c,i),a| a << 2**(sz-i) if c == '1' }
  # => [64, 32, 2] 

#2

n = 2**(98.to_s(2).size-1)
arr = []
while n > 0
  arr << n if 90[n]==1
  n /= 2
end
arr
  #=> [64, 32, 2]
(98).to_s(2).reverse.chars.each_with_index.
   map {|x,i| x=="1" ? 2**i : nil }.compact.reverse

呸!让我们分解一下:

  • 首先获取二进制字符串作为你的例子(98).to_s(2)

  • 我们需要从右侧开始 0 索引,因此 .reverse

  • .chars.each_with_index 为我们提供了 [ '1', 4 ] 位位置

  • 字符对
  • .map 将“1”字符转换为它们的值 2 ** i(即 2 的当前位位置的幂)和“0”为 nil所以它可以被删除

  • .compact 丢弃不需要的 nil

  • .reverse 以 2 的降幂为例

反转字符串,将其映射到每个数字的二进制代码值,拒绝零。可选择再次反转它。

s.reverse.chars.map.with_index{ |c, i| c.to_i * 2**i }.reject{ |b| b == 0 }.reverse

或者您可以使用 each_with_index

将值推送到数组
a = []
s.reverse.each_with_index do |c, i|
  a.unshift c.to_i * 2**i
end

什么可能更快、更易读,但不那么惯用。

这可行:

i = 98
(0...i.bit_length).map { |n| i[n] << n }.reject(&:zero?)
#=> [2, 32, 64]

一步一步:

(0...i.bit_length).map { |n| i[n] }
#=> [0, 1, 0, 0, 0, 1, 1]

(0...i.bit_length).map { |n| i[n] << n }
#=> [0, 2, 0, 0, 0, 32, 64]

(0...i.bit_length).map { |n| i[n] << n }.reject(&:zero?)
#=> [2, 32, 64]

您可能想要 reverse 结果。