yaz*_*azu 85
在Go1中,符文是内置类型.
func Reverse(s string) string {
runes := []rune(s)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes)
}
Run Code Online (Sandbox Code Playgroud)
小智 51
package main
import "fmt"
func main() {
input := "The quick brown ? jumped over the lazy ?"
// Get Unicode code points.
n := 0
rune := make([]rune, len(input))
for _, r := range input {
rune[n] = r
n++
}
rune = rune[0:n]
// Reverse
for i := 0; i < n/2; i++ {
rune[i], rune[n-1-i] = rune[n-1-i], rune[i]
}
// Convert back to UTF-8.
output := string(rune)
fmt.Println(output)
}
Run Code Online (Sandbox Code Playgroud)
小智 24
这是有效的,没有任何关于功能的问题:
func Reverse(s string) (result string) {
for _,v := range s {
result = string(v) + result
}
return
}
Run Code Online (Sandbox Code Playgroud)
Ran*_*ku' 14
这可以通过考虑两件事来解决unicode字符串:
所以这里:
func reverse(s string) string {
o := make([]int, utf8.RuneCountInString(s));
i := len(o);
for _, c := range s {
i--;
o[i] = c;
}
return string(o);
}
Run Code Online (Sandbox Code Playgroud)
Iva*_*hau 13
来自Go示例项目:golang/example/stringutil/reverse.go,作者是Andrew Gerrand
/*
Copyright 2014 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Reverse returns its argument string reversed rune-wise left to right.
func Reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
Run Code Online (Sandbox Code Playgroud)
在反转字符串"bròwn"之后,正确的结果应该是"nwòrb",而不是"nẁorb".
注意字母o上方的坟墓.
要保留Unicode组合字符,例如"as⃝df̅"和反向结果"f̅ds⃝a",
请参阅下面列出的其他代码:
http://rosettacode.org/wiki/Reverse_a_string#Go
pet*_*rSO 10
当Simon发布他的解决方案时,我注意到了这个问题,因为字符串是不可变的,效率非常低.其他提议的解决方案也存在缺陷; 他们不工作或效率低下.
这是一个有效的解决方案,除非字符串无效UTF-8或字符串包含组合字符.
package main
import "fmt"
func Reverse(s string) string {
n := len(s)
runes := make([]rune, n)
for _, rune := range s {
n--
runes[n] = rune
}
return string(runes[n:])
}
func main() {
fmt.Println(Reverse(Reverse("Hello, ??")))
fmt.Println(Reverse(Reverse("The quick brown ? jumped over the lazy ?")))
}
Run Code Online (Sandbox Code Playgroud)
简单的一笔rune:
func ReverseString(s string) string {\n runes := []rune(s)\n size := len(runes)\n for i, j := 0, size-1; i < size>>1; i, j = i+1, j-1 {\n runes[i], runes[j] = runes[j], runes[i]\n }\n return string(runes)\n}\n\nfunc main() {\n fmt.Println(ReverseString("Abcdefg \xe6\xb1\x89\xe8\xaf\xad The God"))\n}\nRun Code Online (Sandbox Code Playgroud)\n: doG ehT \xe8\xaf\xad\xe6\xb1\x89 gfedcbA\nRun Code Online (Sandbox Code Playgroud)\n
这里有太多答案。其中一些是明显的重复项。但是,即使从左起,也很难选择最佳解决方案。
因此,我仔细研究了答案,扔掉了不适用于unicode的答案,并删除了重复项。我对幸存者进行了基准测试,以找到最快的幸存者。因此,这是带归属的结果(如果您注意到我错过的答案,但值得添加,请随时修改基准):
Benchmark_rmuller-4 100000 19246 ns/op
Benchmark_peterSO-4 50000 28068 ns/op
Benchmark_russ-4 50000 30007 ns/op
Benchmark_ivan-4 50000 33694 ns/op
Benchmark_yazu-4 50000 33372 ns/op
Benchmark_yuku-4 50000 37556 ns/op
Benchmark_simon-4 3000 426201 ns/op
Run Code Online (Sandbox Code Playgroud)
所以这是rmuller最快的方法:
func Reverse(s string) string {
size := len(s)
buf := make([]byte, size)
for start := 0; start < size; {
r, n := utf8.DecodeRuneInString(s[start:])
start += n
utf8.EncodeRune(buf[size-start:], r)
}
return string(buf)
}
Run Code Online (Sandbox Code Playgroud)
由于某种原因,我无法添加基准,因此可以从中复制基准PlayGround(您无法在其中运行测试)。重命名并运行go test -bench=.
//Reverse reverses string using strings.Builder. It's about 3 times faster
//than the one with using a string concatenation
func Reverse(in string) string {
var sb strings.Builder
runes := []rune(in)
for i := len(runes) - 1; 0 <= i; i-- {
sb.WriteRune(runes[i])
}
return sb.String()
}
//Reverse reverses string using string
func Reverse(in string) (out string) {
for _, r := range in {
out = string(r) + out
}
return
}
BenchmarkReverseStringConcatenation-8 1000000 1571 ns/op 176 B/op 29 allocs/op
BenchmarkReverseStringsBuilder-8 3000000 499 ns/op 56 B/op 6 allocs/op
Run Code Online (Sandbox Code Playgroud)
使用 strings.Builder 比使用字符串连接快大约 3 倍
这是完全不同的,我会说更多功能方法,未在其他答案中列出:
func reverse(s string) (ret string) {
for _, v := range s {
defer func(r rune) { ret += string(r) }(v)
}
return
}
Run Code Online (Sandbox Code Playgroud)
小智 6
func ReverseString(str string) string {\n output :=""\n for _, char := range str {\n output = string(char) + output\n }\n return output\n}\n\n// "Luizpa" -> "apziuL"\n// "123\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e" -> "\xe8\xaa\x9e\xe6\x9c\xac\xe6\x97\xa5321"\n// "\xe2\x9a\xbd" -> "\xe2\x9a\xbd"\n// "\xc2\xb4a\xc2\xb4b\xc2\xb4c\xc2\xb4" -> "\xc2\xb4c\xc2\xb4b\xc2\xb4a\xc2\xb4"\nRun Code Online (Sandbox Code Playgroud)\n
我写了以下Reverse函数,它尊重UTF8编码和组合字符:
// Reverse reverses the input while respecting UTF8 encoding and combined characters
func Reverse(text string) string {
textRunes := []rune(text)
textRunesLength := len(textRunes)
if textRunesLength <= 1 {
return text
}
i, j := 0, 0
for i < textRunesLength && j < textRunesLength {
j = i + 1
for j < textRunesLength && isMark(textRunes[j]) {
j++
}
if isMark(textRunes[j-1]) {
// Reverses Combined Characters
reverse(textRunes[i:j], j-i)
}
i = j
}
// Reverses the entire array
reverse(textRunes, textRunesLength)
return string(textRunes)
}
func reverse(runes []rune, length int) {
for i, j := 0, length-1; i < length/2; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
}
// isMark determines whether the rune is a marker
func isMark(r rune) bool {
return unicode.Is(unicode.Mn, r) || unicode.Is(unicode.Me, r) || unicode.Is(unicode.Mc, r)
}
Run Code Online (Sandbox Code Playgroud)
我尽力使其尽可能高效和可读.这个想法很简单,遍历符文寻找组合字符,然后将组合字符的符文反转到原位.一旦我们完全覆盖了它们,就可以在适当的位置反转整个字符串的符文.
假设我们想要反转这个字符串bròwn.它ò由两个符文表示,一个代表"坟墓" o,另一个\u0301a代表"坟墓".
为简单起见,让我们代表这样的字符串bro'wn.我们要做的第一件事就是寻找组合字符并反转它们.所以现在我们有了字符串br'own.最后,我们将整个字符串反转并最终结束nwo'rb.这是作为返回给我们的nwòrb
如果您想使用它,可以在https://github.com/shomali11/util找到它.
以下是一些测试用例,展示了几种不同的场景:
func TestReverse(t *testing.T) {
assert.Equal(t, Reverse(""), "")
assert.Equal(t, Reverse("X"), "X")
assert.Equal(t, Reverse("b\u0301"), "b\u0301")
assert.Equal(t, Reverse("?"), "?")
assert.Equal(t, Reverse("Les Mise\u0301rables"), "selbare\u0301siM seL")
assert.Equal(t, Reverse("ab\u0301cde"), "edcb\u0301a")
assert.Equal(t, Reverse("This `\xc5` is an invalid UTF8 character"), "retcarahc 8FTU dilavni na si `?` sihT")
assert.Equal(t, Reverse("The quick bròwn ? jumped over the lazy ?"), "? yzal eht revo depmuj ? nwòrb kciuq ehT")
}
Run Code Online (Sandbox Code Playgroud)
我认为适用于 unicode 的版本。它基于 utf8.Rune 函数构建:
func Reverse(s string) string {
b := make([]byte, len(s));
for i, j := len(s)-1, 0; i >= 0; i-- {
if utf8.RuneStart(s[i]) {
rune, size := utf8.DecodeRuneInString(s[i:len(s)]);
utf8.EncodeRune(rune, b[j:j+size]);
j += size;
}
}
return string(b);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
54182 次 |
| 最近记录: |