我想要计算两个字节之间的海明距离,例如
HammingDist(byte(255), byte(0)) == 8
我需要获取每个字节中的位,但是我在任何内置包中都找不到相应的函数。因此,如果给定byte(1)
,如何获得其二进制表示形式00000001?
我想要计算两个字节之间的海明距离,例如
HammingDist(byte(255), byte(0)) == 8
我需要获取每个字节中的位,但是我在任何内置包中都找不到相应的函数。因此,如果给定byte(1)
,如何获得其二进制表示形式00000001?
fmt.Sprintf("%08b", ...)
来看到位的可视化表示,正如其他人已经建议的那样。位与运算
,这个字节的第n位设置为1,其余位设置为0(也称为掩码)。换句话说,那个另外的字节(掩码)就是2n-1。fmt.Print(13 & 1) // Output: 1 -> 1
fmt.Print(13 & 2) // Output: 0 -> 0
fmt.Print(13 & 4) // Output: 4 -> 1
fmt.Print(13 & 8) // Output: 8 -> 1
// Not necessary to continue, but shown for the sake of the example
fmt.Print(13 & 16) // Output: 0 -> 0
fmt.Print(13 & 32) // Output: 0 -> 0
fmt.Print(13 & 64) // Output: 0 -> 0
fmt.Print(13 & 128) // Output: 0 -> 0
func hamming(a, b []byte) (int, error) {
if len(a) != len(b) {
return 0, errors.New("a b are not the same length")
}
diff := 0
for i := 0; i < len(a); i++ {
b1 := a[i]
b2 := b[i]
for j := 0; j < 8; j++ {
mask := byte(1 << uint(j))
if (b1 & mask) != (b2 & mask) {
diff++
}
}
}
return diff, nil
}
fmt.Sprintf("%08b", byte(1)) 是一个好方法。它展示了数字的内部存储方式。计算汉明距离的示例(非常无聊)可能如下:
package main
import (
"fmt"
)
func HamDist(n1,n2 uint8) uint8 {
var w uint8 = 0
if n1&1 != n2&1 {
w++
}
if n1&2 != n2&2 {
w++
}
if n1&4 != n2&4 {
w++
}
if n1&8 != n2&8 {
w++
}
if n1&16 != n2&16 {
w++
}
if n1&32 != n2&32 {
w++
}
if n1&64 != n2&64 {
w++
}
if n1&128 != n2&128 {
w++
}
return w
}
func main() {
fmt.Println(HamDist(255,0))
}
现在给你一些任务:
import "math/bits"
bits.OnesCount8(byte(0) ^ byte(255))
fmt.Printf("%08b", YourNumber)
您也可以使用%016b
或%032b
或其他任何格式。
func HammingDistance(s1, s2 string) (int, error) {
if len(s1) != len(s2) {
return 0, fmt.Errorf("Hamming distance of strings of different lengths %d and %d", len(s1), len(s2))
}
b1 := []byte(s1)
b2 := []byte(s2)
distance := 0
for i := range b1 {
xored := b1[i] ^ b2[i]
for j := 0; j < 8; j++ {
distance += int(xored & 1)
xored = xored >> 1
}
}
return distance, nil
}
要计算两个字节的汉明距离,您只需要内部for循环。