为了账号安全,请及时绑定邮箱和手机立即绑定

Go:将符文(字符串)转换为二进制的字符串表示

Go:将符文(字符串)转换为二进制的字符串表示

Go
ITMISS 2021-09-13 20:00:14
这是以防万一其他人正在学习 Golang 并且想知道如何从字符串转换为二进制字符串表示。长话短说,我一直在查看标准库却找不到正确的调用。所以我从类似于以下内容开始:func RuneToBinary(r rune) string {    var buf bytes.Buffer    b := []int64{128, 64, 32, 16, 8, 4, 2, 1}    v := int64(r)    for i := 0; i < len(b); i++ {        t := v-b[i]        if t >= 0 {           fmt.Fprintf(&buf, "1")           v = t        } else {           fmt.Fprintf(&buf, "0")        }    }    return buf.String()}这是一个好花花公子,但一对夫妇环顾四周,我发现,我应该一直在使用几天后fmt包代替,只是格式化rune有%b%:var r runefmt.Printf("input: %b ", r)有一个更好的方法吗?
查看完整描述

1 回答

?
慕容森

TA贡献1853条经验 获得超18个赞

标准库支持


fmt.Printf("%b", r)- 该解决方案已经非常紧凑且易于编写和理解。如果您需要结果为string,则可以使用模拟Sprintf()函数:


s := fmt.Sprintf("%b", r)

您还可以使用strconv.FormatInt()具有多种类型的函数int64(因此您首先必须转换您的rune)和一个基数,您可以在其中传递2以获得二进制表示的结果:


s := strconv.FormatInt(int64(r), 2)

请注意,在 Gorune中只是 的别名int32,这两种类型是一种且相同(只是您可以通过 2 个名称来引用它)。


手动执行(“简单但天真”):


如果您想“手动”执行此操作,则有一个比原始解决方案简单得多的解决方案。您可以使用 测试最低位r & 0x01 == 0并使用 移动所有位r >>= 1。只需“循环”所有位并附加"1"或"0"取决于位:


请注意,这仅用于演示,它在性能方面远非最佳(生成“冗余” string):


func RuneToBin(r rune) (s string) {

    if r == 0 {

        return "0"

    }

    for digits := []string{"0", "1"}; r > 0; r >>= 1 {

        s = digits[r&1] + s

    }

    return

}

注意:函数不处理负数。如果你还想处理负数,你可以先检查它并处理它的正值,并以减号开始返回值'-'。这也适用于下面的其他手动解决方案。


手动性能方面的解决方案:


对于快速解决方案,我们不应该附加字符串。由于 Go 中的字符串只是使用 UTF-8 编码的字节切片,因此附加数字只是附加符文的字节值'0'或'1'只是一个字节(不是多个)。所以我们可以分配一个足够大的缓冲区/数组(rune是 32 位,所以最多 32 个二进制数字),然后向后填充,这样我们甚至不必在最后反转它。并在最后返回转换为数组的使用部分string。请注意,我什至没有调用内置append函数来附加二进制数字,我只是设置了在其中构建结果的数组的相应元素:


func RuneToBinFast(r rune) string {

    if r == 0 {

        return "0"

    }

    b, i := [32]byte{}, 31

    for ; r > 0; r, i = r>>1, i-1 {

        if r&1 == 0 {

            b[i] = '0'

        } else {

            b[i] = '1'

        }

    }

    return string(b[i+1:])

}


查看完整回答
反对 回复 2021-09-13
  • 1 回答
  • 0 关注
  • 285 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信