5

efficientlyエリクサーでビット文字列のハミング重みを計算するにはどうすればよいですか?

例:0b0101101001ハミング重みが 5 である (つまり、5 ビットが設定されている)

私の試み:

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

1 に答える 1

7

これは、(私にとって)意図をより明確に示している、より優れたパフォーマンスのソリューションです。

for(<<bit::1 <- :binary.encode_unsigned(n)>>, do: bit) |> Enum.sum

2 進数 100.000 桁の benchfella を使用したベンチマーク:

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

ベンチマーク結果:

$ 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
于 2015-12-02T18:54:57.743 に答える