假设我有一个整数98。 该字符串的二进制表示形式为:
(98).to_s(2) # 1100010
现在我想将这个二进制字符串转换为所有已设置位的整数数组。这会给我:
[64,32,2]
我该怎么做?
更新:将int转换为int数组不一定需要涉及String,这正是我所知道的。我假设非String操作也会更快。
Ruby看到所有这些不同的方法来处理这个问题真是太棒了!
答案 0 :(得分:6)
这样可行:
i = 98
(0...i.bit_length).map { |n| i[n] << n }.reject(&:zero?)
#=> [2, 32, 64]
Fixnum#bit_length
返回最高“1”位的位置Fixnum#[n]
返回整数的 n 位,即0
或1
Fixnum#<<
将位移到左侧。 1 << n
相当于2 n 一步一步:
(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
结果。
答案 1 :(得分:2)
以下是两种方法:
<强>#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]
答案 2 :(得分: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-index,因此.reverse
.chars.each_with_index
为比特位置的角色提供[ '1', 4 ]
对等
.map
转换&#34; 1&#34;字符值2 ** i
(即2到当前位位置的幂)和&#34; 0&#34;到nil
,以便删除
.compact
放弃您不想要的nil
值
.reverse
具有2的降序功能作为示例
答案 3 :(得分: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
可能更快,更易读,但不那么惯用。