Elixir中BitString的位计数或汉明重量?

时间:2015-12-02 17:42:31

标签: elixir bitstring hammingweight

请问efficiently怎样才能计算出灵药中位串的汉明重量?

示例:0b0101101001的汉明权重为5(即设置为5位)

我的尝试:

iex> Enum.count(Integer.to_char_list(n,2),&(&1===49)) 

1 个答案:

答案 0 :(得分:5)

这是一个表现更好的解决方案,对我来说也更清楚地表明了意图:

Benchfella.start

defmodule HammingBench do
  use Benchfella

  @n Stream.repeatedly(fn -> Enum.random [0, 1] end)
    |> Enum.take(100_000)
    |> Enum.join
    |> String.to_integer(2)

  bench "CharlesO" do
    Enum.count(Integer.to_char_list(@n,2),&(&1===49)) 
  end

  bench "Patrick Oscity" do
    for(<<bit::1 <- :binary.encode_unsigned(@n)>>, do: bit) |> Enum.sum
  end
end

使用具有100.000二进制数字的benchfella进行基准测试:

$ mix bench
Compiled lib/hamming_bench.ex
Generated hamming_bench app
Settings:
  duration:      1.0 s

## HammingBench
[20:12:03] 1/2: Patrick Oscity
[20:12:06] 2/2: CharlesO

Finished in 8.4 seconds

## HammingBench
Patrick Oscity         500   4325.79 µs/op
CharlesO                 1   5754094.00 µs/op

基准测试结果:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
    <solid android:color="@android:color/transparent" />
    <stroke android:width="10dp" android:color="@color/color_gray5_eeeeee" />
    <corners android:radius="10px" />
</shape>