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]
Fixnum#bit_length
returns最高“1”位的位置
Fixnum#[n]
returns 整数的第 n 位,即 0
或 1
Fixnum#<<
将位向左移动。 1 << n
等价于 2n
一步一步:
(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
结果。
假设我有一个整数 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]
Fixnum#bit_length
returns最高“1”位的位置Fixnum#[n]
returns 整数的第 n 位,即0
或1
Fixnum#<<
将位向左移动。1 << n
等价于 2n
一步一步:
(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
结果。