在go语言里面优雅的反转字符串

在go语言里面优雅的反转字符串

一、用于反转ascii字符的方法

        通常,说到反转字符串,由于string的不变性,就转为[]byte然后处理

func reverseBytes(s string) string {
	r := []byte(s)
	for i := 0; i < len(s); i++ {
	    r[i] = s[len(s)-1-i]
	}
	return string(r)
}

        这种反转适用于 ascII的字符,因为byte底层为uint8,一字节,最多表示256种不同字符,如果使用此方法的字符串包含UTF-8的多字节表示的情况,将不能获得正确结果。

二、反转UTF-8的情况,需要使用rune

        rune字符底层为uint32,4字节长度,适用于多字节编码的情况,此处处理UTF-8的情况

func reverseCodePoints(s string) string {
	r := make([]rune, len(s))
	start := len(s)
	for _, c := range s {
		// quietly skip invalid UTF-8
		if c != utf8.RuneError {
			start--
			r[start] = c
		}
	}
	return string(r[start:])
}

三、部分特殊字符,需要多字节段合并,才能正确读取并反转

        对于这种特殊情况,需要特殊处理合并,下面展示一种。

func reversePreservingCombiningCharacters(s string) string {
	if s == "" {
		return ""
	}
	p := []rune(s)
	r := make([]rune, len(p))
	start := len(r)
	for i := 0; i < len(p); {
		// quietly skip invalid UTF-8
		if p[i] == utf8.RuneError {
			i++
			continue
		}
		j := i + 1
		for j < len(p) && (unicode.Is(unicode.Mn, p[j]) ||
			unicode.Is(unicode.Me, p[j]) || unicode.Is(unicode.Mc, p[j])) {
			j++
		}
		for k := j - 1; k >= i; k-- {
			start--
			r[start] = p[k]
		}
		i = j
	}
	return string(r[start:])

测试代码

func main() {
	test("asdf")
	test("as⃝df̅中国")
}

func test(s string) {
	fmt.Println("\noriginal:      ", []byte(s), s)
	r := reverseBytes(s)
	fmt.Println("reversed bytes:", []byte(r), r)
	fmt.Println("original code points:", []rune(s), s)
	r = reverseCodePoints(s)
	fmt.Println("reversed code points:", []rune(r), r)
	r = reversePreservingCombiningCharacters(s)
	fmt.Println("combining characters:", []rune(r), r)
}
//original:       [97 115 100 102] asdf
//reversed bytes: [102 100 115 97] fdsa
//original code points: [97 115 100 102] asdf
//reversed code points: [102 100 115 97] fdsa
//combining characters: [102 100 115 97] fdsa
//
//original:       [97 115 226 131 157 100 102 204 133 228 184 173 229 155 189] as⃝df̅中国
//reversed bytes: [189 155 229 173 184 228 133 204 102 100 157 131 226 115 97] ��學��fd���sa
//original code points: [97 115 8413 100 102 773 20013 22269] as⃝df̅中国
//reversed code points: [22269 20013 773 102 100 8413 115 97] 国中̅fd⃝sa
//combining characters: [22269 20013 102 773 100 115 8413 97] 国中f̅ds⃝a

参考文献:How to reverse a string in Go? - Stack Overflow

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值