2016-09-04 11 views
3

我在寻找一个快捷功能(无串)计算整数的二进制描述领头的人在Ruby中

leading_ones(0b11101)  # =>3 
leading_ones(0b1111000110) # =>4 

谢谢你的努力!

+0

你为什么需要这个,它属于一种方法你尝试过什么 –

+0

解决更大的问题,请参阅:http://stackoverflow.com/questions/39318312/binary-calculations-ruby – user3756502

+0

似乎是一个家庭作业问题(为什么不使用字符串?),但我渴望看到一个答案,无论出于好奇 –

回答

2
def leading_ones(n) 
    nbr = 0 
    (n.bit_length-1).downto(0) do |i| 
    return nbr if n[i].zero? 
    nbr += 1 
    end 
    nbr 
end 

leading_ones(6) 
    #=> 2 

注意6.to_s(2) #=> "110"。这使用方法Fixnum#bit_lengthFixnum#[]

+0

非常感谢!我不知道函数bit_length,只是发现我使用的另一个Math.log2创建舍入误差来限制它。您提供了我的方法的正确实施。 非常感谢! – user3756502

1

这可能不是最有效的解决方案,但它的工作原理。

def leading_ones(num) 
    counter = 0 
    while num > 0 
    if num % 2 == 0 
     counter = 0 
    else 
     counter += 1 
    end 

    num = num/2 
    end 
    counter 
end 

leading_ones(0b111) # => 3 
leading_ones(0b11101) # => 3 
leading_ones(0b111101) # => 4 
leading_ones(0b1000) # => 1 
leading_ones(0b01000) # => 1 
+0

谢谢你kallax。我记得你从我关于这个问题的第一个问题:http://stackoverflow.com/questions/39297163/trying-to-store-many-rectangles-without-duplicate-areas-efficiently-in-ruby 任何想法没有一个循环?那太好了! – user3756502

0

这是我的做法至今:

def leading_ones(arg) 
    c=0 
    log=Math.log2(arg).to_i 
    max_index.downto(0){|i| 
     if arg[i]==1 
      c+=1 
     else 
      return c 
     end 
    } 
    return c 
end 

没有环的任何想法?我认为应该可以在没有迭代的情况下计算另一个数字。

补充说:

好吧,这已经相当快,我想我会利用这个解决方案。但另一个没有循环将是完美的:-)

想法欢迎!

补充说:

不要用我的方法。它会产生舍入误差。查看正确版本的选定答案。

1

你的版本与循环实际上是一个快一点的,但FWIW,这里是没有环的一个版本:

def leading_ones(n) 
    # Number of bits needed to hold `n` as an unsigned integer 
    bits = n.bit_length 
    # `digits` bits, all on 
    max_possible = (1 << bits) - 1 
    # Flips all of `n`'s bits 
    flipped = n^max_possible 
    # First right-index of a zero in `n`, or the first index of a 1 in `flipped` 
    first_zero_rindex = flipped.bit_length 
    # Left-index of the first zero 
    first_zero_index = bits - first_zero_rindex 
    first_zero_index 
end 
+0

在引擎盖下,'bit_length'基本上是一个循环。顺便说一句,你可以使用'(1 << bits) - 1'来避免昂贵的指数运算。 – Stefan

+0

当然,引擎盖下面有很多回路,至少在硬件层面上。但是如果我在高层次上添加额外的循环,它总体上会变慢。谢谢你们的贡献! – user3756502

+0

@Stefan我很惊讶Ruby不会将'2 ** n'优化为'1 << n',其中n是一个正整数。尽管如此,我仍然编辑了我的答案,使用“max_possible”的bitshifting。 – nloveladyallen