122

Goで単純な文字列を逆にするにはどうすればよいですか?

4

33 に答える 33

123

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)
}
于 2012-04-05T14:43:12.210 に答える
59

golang-nuts メーリング リストの Russ Cox は、次のように提案しています。

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)
}
于 2009-11-18T07:29:26.340 に答える
41

これは、関数をいじることなく機能します。

func Reverse(s string) (result string) {
  for _,v := range s {
    result = string(v) + result
  }
  return 
}
于 2011-02-11T04:07:21.010 に答える
20

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)
}

文字列を逆にするために遊び場に行く

文字列「bròwn」を反転した後、正しい結果は「nẁorb」ではなく「nwòrb」になるはずです。
文字 o の上の墓に注意してください。


「as⃝df̅」などの文字を組み合わせて「f̅ds⃝a」という逆の結果を示す Unicode を保持するには、
以下にリストされている別のコードを参照してください。

http://rosettacode.org/wiki/Reverse_a_string#Go

于 2015-06-22T07:14:24.143 に答える
15

これは、次の 2 つのことを考慮して、Unicode 文字列で機能します。

  • 範囲は、Unicode 文字を列挙することによって文字列に作用します
  • string は、各要素が Unicode 文字である int スライスから構築できます。

だからここに行く:

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);
}
于 2009-11-18T18:33:29.873 に答える
14

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 犬")))
}
于 2011-02-11T07:14:57.687 に答える
13

ここには答えが多すぎます。それらのいくつかは明らかな複製です。しかし、左からでも最適解を選ぶのは難しい。

だから私は答えを調べ、ユニコードで機能しないものを捨て、重複も削除しました。生存者をベンチマークして、最速を見つけました。帰属表示付きの結果は次のとおりです (私が見逃したが追加する価値のある回答に気付いた場合は、ベンチマークを自由に変更してください)。

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

したがって、 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)
}

何らかの理由でベンチマークを追加できないので、そこからコピーできますPlayGround(そこでテストを実行することはできません)。名前を変更して実行しますgo test -bench=.

于 2015-12-30T00:17:55.253 に答える
9
//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

string.Builder を使用すると、文字列連結を使用するよりも約 3 倍高速です

于 2019-08-25T10:57:30.763 に答える
6

これはまったく異なります。他の回答には記載されていませんが、より機能的なアプローチと言えます。

func reverse(s string) (ret string) {
    for _, v := range s {
        defer func(r rune) { ret += string(r) }(v)
    }
    return
}
于 2016-06-24T15:43:57.870 に答える
4

これは最速の実装です

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)
}

const (
    s       = "The quick brown 狐 jumped over the lazy 犬"
    reverse = "犬 yzal eht revo depmuj 狐 nworb kciuq ehT"
)

func TestReverse(t *testing.T) {
    if Reverse(s) != reverse {
        t.Error(s)
    }
}

func BenchmarkReverse(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Reverse(s)
    }
}
于 2013-11-26T18:56:53.497 に答える
2

これは確かに最もメモリ効率の高いソリューションではありませんが、「単純な」UTF-8 セーフ ソリューションの場合、次のようにすれば作業が完了し、ルーン文字が壊れることはありません。

私の意見では、このページで最も読みやすく、理解しやすいものです。

func reverseStr(str string) (out string) {
    for _, s := range str {
        out = string(s) + out
    }

    return
}
于 2016-06-03T20:03:00.160 に答える
1

次の 2 つの方法は、合成文字を保持する最速のソリューションよりも高速に実行されますが、ベンチマークの設定に何かが欠けているわけではありません。

//input string s
bs := []byte(s)
var rs string
for len(bs) > 0 {
    r, size := utf8.DecodeLastRune(bs)
    rs += fmt.Sprintf("%c", r)
    bs = bs[:len(bs)-size]
} // rs has reversed string

これに触発された2番目の方法

//input string s
bs := []byte(s)
cs := make([]byte, len(bs))
b1 := 0
for len(bs) > 0 {
    r, size := utf8.DecodeLastRune(bs)
    d := make([]byte, size)
    _ = utf8.EncodeRune(d, r)
    b1 += copy(cs[b1:], d)
    bs = bs[:len(bs) - size]
} // cs has reversed bytes
于 2016-09-03T16:02:32.147 に答える
1

注:この回答は 2009 年のものであるため、現在はおそらくより良い解決策が存在します。


少し「回りくどい」ように見え、おそらくあまり効率的ではありませんが、Reader インターフェイスを使用して文字列から読み取る方法を示しています。IntVectors は、utf8 文字列を操作する場合のバッファーとしても非常に適しているようです。

「サイズ」部分を省略し、Insert でベクターに挿入するとさらに短くなりますが、新しいルーンが追加されるたびにベクター全体を 1 つ押し戻す必要があるため、効率が悪いと思います。 .

このソリューションは間違いなく utf8 文字で機能します。

package main

import "container/vector";
import "fmt";
import "utf8";
import "bytes";
import "bufio";


func
main() {
    toReverse := "Smørrebrød";
    fmt.Println(toReverse);
    fmt.Println(reverse(toReverse));
}

func
reverse(str string) string {
    size := utf8.RuneCountInString(str);
    output := vector.NewIntVector(size);
    input := bufio.NewReader(bytes.NewBufferString(str));
    for i := 1; i <= size; i++ {
        rune, _, _ := input.ReadRune();
        output.Set(size - i, rune);
    }
    return string(output.Data());
}
于 2009-11-18T12:40:57.223 に答える
1
func Reverse(s string) string {
    r := []rune(s)
    var output strings.Builder
    for i := len(r) - 1; i >= 0; i-- {
        output.WriteString(string(r[i]))
    }

    return output.String()
}
于 2020-10-10T20:41:26.947 に答える
0

ユニコードで動作すると思うバージョン。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);
}
于 2009-11-18T04:11:10.270 に答える
0

以下のコードを試してください:

package main

import "fmt"

func reverse(s string) string {
    chars := []rune(s)
    for i, j := 0, len(chars)-1; i < j; i, j = i+1, j-1 {
        chars[i], chars[j] = chars[j], chars[i]
    }
    return string(chars)
}

func main() {
    fmt.Printf("%v\n", reverse("abcdefg"))
}

詳細については、http: //golangcookbook.com/chapters/strings/reverse/
およびhttp://www.dotnetperls.com/reverse-string-goを確認してください。

于 2016-06-29T14:33:17.533 に答える
-1
package reverseString

import "strings"

// ReverseString - output the reverse string of a given string s
func ReverseString(s string) string {

    strLen := len(s)

    // The reverse of a empty string is a empty string
    if strLen == 0 {
        return s
    }

    // Same above
    if strLen == 1 {
        return s
    }

    // Convert s into unicode points
    r := []rune(s)

    // Last index
    rLen := len(r) - 1

    // String new home
    rev := []string{}

    for i := rLen; i >= 0; i-- {
        rev = append(rev, string(r[i]))
    }

    return strings.Join(rev, "")
}

Test

package reverseString

import (
    "fmt"
    "strings"
    "testing"
)

func TestReverseString(t *testing.T) {

    s := "GO je úžasné!"
    r := ReverseString(s)

    fmt.Printf("Input: %s\nOutput: %s", s, r)

    revR := ReverseString(r)

    if strings.Compare(s, revR) != 0 {
        t.Errorf("Expecting: %s\n. Got: %s\n", s, revR)
    }
}

Output

Input: GO je úžasné!
Output: !énsažú ej OG
PASS
ok      github.com/alesr/reverse-string 0.098s
于 2015-12-12T13:19:08.897 に答える
-1
func reverseStr(b string) {
for _, v := range []rune(b) {
    defer fmt.Printf("%c", v)

}
 }

Defer は LIFO - Last in First Out であるため、これに役立ちます。

于 2021-02-17T15:56:20.800 に答える