Go 中如何反转字符串?
我们如何在 Go 中反转一个简单的字符串?
How can we reverse a simple string in Go?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我们如何在 Go 中反转一个简单的字符串?
How can we reverse a simple string in Go?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(30)
带有
rune
的简笔画:A simple stroke with
rune
:这是完全不同的,我会说更实用的方法,未在其他答案中列出:
Here is quite different, I would say more functional approach, not listed among other answers:
这是最快的实施
This is the fastest implementation
您还可以导入现有的实现:
然后:
或者反转包含 unicode 组合字符的字符串:
这些实现在反转时支持 unicode 多字节和组合字符的正确排序。
注意:许多编程语言中的内置字符串反转函数不保留组合,并且识别组合字符需要更多的执行时间。
You could also import an existing implementation:
Then:
Or to reverse a string including unicode combining characters:
These implementations supports correct ordering of unicode multibyte and combing characters when reversed.
Note: Built-in string reverse functions in many programming languages do not preserve combining, and identifying combining characters requires significantly more execution time.
该代码完整地保留了组合字符的序列,并且
也应该适用于无效的 UTF-8 输入。
如果 unicode/norm 原语可能会更有效一些
允许迭代字符串的边界而无需
分配。另请参阅https://code.google.com/p/go/issues /detail?id=9055 。
This code preserves sequences of combining characters intact, and
should work with invalid UTF-8 input too.
It could be a little more efficient if the unicode/norm primitives
allowed iterating through the boundaries of a string without
allocating. See also https://code.google.com/p/go/issues/detail?id=9055 .
如果需要处理字素簇,请使用 unicode 或 regexp 模块。
If you need to handle grapheme clusters, use unicode or regexp module.
它肯定不是最高效的内存解决方案,但对于“简单”的 UTF-8 安全解决方案,以下内容将完成工作并且不会破坏符文。
在我看来,这是该页面上最具可读性和最容易理解的内容。
It's assuredly not the most memory efficient solution, but for a "simple" UTF-8 safe solution the following will get the job done and not break runes.
It's in my opinion the most readable and understandable on the page.
以下两种方法的运行速度比最快的保留组合字符的解决方案运行得更快,但这并不是说我错过了一些东西我的基准设置。
第二种方法的灵感来自this
The following two methods run faster than the fastest solution that preserve combining characters, though that's not to say I'm missing something in my benchmark setup.
Second method inspired by this
简单、甜蜜、高性能
Simple, Sweet and Performant
注意:这个答案来自 2009 年,所以现在可能有更好的解决方案。
看起来有点“迂回”,并且可能不是很有效,但说明了如何使用 Reader 接口来读取字符串。在处理 utf8 字符串时,IntVector 似乎也非常适合作为缓冲区。
当省略“大小”部分并通过插入插入到向量中时,它会更短,但我想这会效率较低,因为每次添加新符文时,整个向量都需要向后推一。
这个解决方案肯定适用于 utf8 字符。
NOTE: This answer is from 2009, so there are probably better solutions out there by now.
Looks a bit 'roundabout', and probably not very efficient, but illustrates how the Reader interface can be used to read from strings. IntVectors also seem very suitable as buffers when working with utf8 strings.
It would be even shorter when leaving out the 'size' part, and insertion into the vector by Insert, but I guess that would be less efficient, as the whole vector then needs to be pushed back by one each time a new rune is added.
This solution definitely works with utf8 characters.
按单词反转字符串是一个类似的过程。首先,我们将字符串转换为字符串数组,其中每个条目都是一个单词。接下来,我们对该数组应用正常的反向循环。最后,我们将结果重新组合成一个字符串,然后将其返回给调用者。
Reversing a string by word is a similar process. First, we convert the string into an array of strings where each entry is a word. Next, we apply the normal reverse loop to that array. Finally, we smush the results back together into a string that we can return to the caller.
另一个技巧是使用内置语言功能,例如
defer
:Another hack is to use built-in language features, for example,
defer
:对于简单的字符串,可以使用这样的结构:
对于 Unicode 字符串,它可能如下所示:
For simple strings it possible to use such construction:
For Unicode strings it might look like this:
识别 unicode 代码点是一回事,但是字素簇又如何呢?
例如,
Recognising unicode code points is one thing, but how about grapheme clusters?
For example, ????☠️ is composed from 4 unicode code points / runes, and reversing such a string on the basis of runes will produce garbage. Not good.
Read more about Unicode segmentation in rivo/uniseg docs.
Here's the reversal of a string, using this package:
我认为适用于 unicode 的版本。它基于 utf8.Rune 函数构建:
A version which I think works on unicode. It is built on the utf8.Rune functions:
符文是一种类型,所以使用它。此外,Go 不使用分号。
rune is a type, so use it. Moreover, Go doesn't use semicolons.
尝试下面的代码:
有关更多信息,请检查 http://golangcookbook.com/chapters/strings/reverse/
和 http://www.dotnetperls.com/reverse-string-go
try below code:
for more info check http://golangcookbook.com/chapters/strings/reverse/
and http://www.dotnetperls.com/reverse-string-go
字符串在 golang 中是不可变的对象,与 C 不同,golang 中不可能进行原地反转。
使用 C ,你可以做类似的事情,
但是使用 golang,接下来的一个,首先使用 byte 将输入转换为字节,然后在反转后反转字节数组,在返回之前转换回字符串。仅适用于非 unicode 类型字符串。
Strings are immutable object in golang, unlike C inplace reverse is not possible with golang.
With C , you can do something like,
But with golang, following one, uses byte to convert the input into bytes first and then reverses the byte array once it is reversed, convert back to string before returning. works only with non unicode type string.
在 Go1 中,符文是一种内置类型。
In Go1 rune is a builtin type.
golang-nuts 邮件列表中的 Russ Cox 建议
Russ Cox, on the golang-nuts mailing list, suggests
这是可行的,无需对函数进行任何处理:
This works, without all the mucking about with functions:
这里有太多的答案。其中一些是明显的重复。但即使从左边的方案中,也很难选择最佳方案。
所以我浏览了答案,扔掉了对 unicode 不起作用的答案,并删除了重复项。我对幸存者进行了基准测试,以找到最快的。所以这里是带有归因的结果(如果您注意到我错过了但值得添加的答案,请随意修改基准):
所以这里是rmuller 的最快方法:
由于某种原因,我无法添加基准,因此您可以从 PlayGround (您无法在那里运行测试)。重命名并运行
go test -bench=.
There are too many answers here. Some of them are clear duplicates. But even from the left one, it is hard to select the best solution.
So I went through the answers, thrown away the one that does not work for unicode and also removed duplicates. I benchmarked the survivors to find the fastest. So here are the results with attribution (if you notice the answers that I missed, but worth adding, feel free to modify the benchmark):
So here is the fastest method by rmuller:
For some reason I can't add a benchmark, so you can copy it from PlayGround (you can't run tests there). Rename it and run
go test -bench=.
来自 Go 示例项目:golang/example/stringutil/reverse.go, 作者:Andrew Gerrand
Go Playground 反转字符串
反转字符串“bròwn”后,正确的结果应该是“nwòrb”,而不是“nẁorb”。
注意字母o上方的坟墓。
为了保留 Unicode 组合字符,例如“as⃝df̅”与反向结果“f̅ds⃝a”,
请参考下面列出的另一个代码:
http://rosettacode.org/wiki/Reverse_a_string#Go
From Go example projects: golang/example/stringutil/reverse.go, by Andrew Gerrand
Go Playground for reverse a string
After reversing string "bròwn", the correct result should be "nwòrb", not "nẁorb".
Note the grave above the letter o.
For preserving Unicode combining characters such as "as⃝df̅" with reverse result "f̅ds⃝a",
please refer to another code listed below:
http://rosettacode.org/wiki/Reverse_a_string#Go
这通过考虑两件事来处理 unicode 字符串:
所以事情是这样的:
This works on unicode strings by considering 2 things:
So here it goes:
我编写了以下尊重 UTF8 编码和组合字符的
Reverse
函数:我尽力使其尽可能高效和可读。这个想法很简单,遍历符文寻找组合字符,然后就地反转组合字符的符文。一旦我们将它们全部覆盖,也将整个字符串的符文反转到位。
假设我们要反转该字符串
bròwn
。ò
由两个符文表示,一个代表o
,另一个代表代表“坟墓”的 unicode\u0301a
。为了简单起见,我们将字符串表示为
bro'wn
。我们要做的第一件事是寻找组合字符并将其反转。现在我们有了字符串br'own
。最后,我们反转整个字符串并以nwo'rb
结束。这将作为nwòrb
返回给我们,您可以在这里找到它 https://github.com/ shomali11/util 如果你想使用它。
以下是一些测试用例,展示了几种不同的场景:
I wrote the following
Reverse
function which respects UTF8 encoding and combined characters:I did my best to make it as efficient and readable as possible. The idea is simple, traverse through the runes looking for combined characters then reverse the combined characters' runes in-place. Once we have covered them all, reverse the runes of the entire string also in-place.
Say we would like to reverse this string
bròwn
. Theò
is represented by two runes, one for theo
and one for this unicode\u0301a
that represents the "grave".For simplicity, let's represent the string like this
bro'wn
. The first thing we do is look for combined characters and reverse them. So now we have the stringbr'own
. Finally, we reverse the entire string and end up withnwo'rb
. This is returned to us asnwòrb
You can find it here https://github.com/shomali11/util if you would like to use it.
Here are some test cases to show a couple of different scenarios:
当Simon发布他的解决方案,由于字符串是不可变的,效率非常低。其他提出的解决方案也存在缺陷;他们不工作或者效率低下。
这是一个有效的解决方案,除非字符串不是有效的 UTF-8 或字符串包含组合字符。
I noticed this question when Simon posted his solution which, since strings are immutable, is very inefficient. The other proposed solutions are also flawed; they don't work or they are inefficient.
Here's an efficient solution that works, except when the string is not valid UTF-8 or the string contains combining characters.
使用 strings.Builder 比使用字符串连接快大约 3 倍
Using strings.Builder is about 3 times faster than using string concatenation