请问efficiently如何计算灵丹妙药中一根串的汉明重量?
例如:0b0101101001的汉明重量为5(即5位)。
我的尝试:
iex> Enum.count(Integer.to_char_list(n,2),&(&1===49)) 发布于 2015-12-02 18:54:57
这里有一个更好的解决方案,它(对我来说)也更清楚地显示了它的意图:
for(<<bit::1 <- :binary.encode_unsigned(n)>>, do: bit) |> Enum.sum使用具有100.000位二进制数的基准测试:
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发布于 2022-06-26 08:16:03
虽然Patrick的答案对于正整数是正确的,但对于负数,它将失败,因为:binary.encode_unsigned/1不处理它们。
使用<<>>
相反,我建议使用Elixir的强大的<<>>位字符串运算符(它看起来更好看):
Enum.sum(for << bit::1 <- <<n>> >>, do: bit))还可以将整数大小指定为16位、32位或其他任何内容:
<<n::integer-32>>在一次传递中计数位
作为另一种方法,您还可以一次直接计数位数,而不是先获取所有比特,然后再对它们进行求和:
defmodule HammingWeight do
def weight(int) when is_integer(int) do
w(<<int>>, 0)
end
defp w(<<>>>, count), do: count
defp w(<<0::1, rest::bits>>, count), do: w(rest, count)
defp w(<<1::1, rest::bits>>, count), do: w(rest, count + 1)
endhttps://stackoverflow.com/questions/34049445
复制相似问题