Come invertire una stringa in Go?


103

Come possiamo invertire una semplice stringa in Go?


1
Per quanto ho capito, le soluzioni fornite di seguito non funzionano con caratteri precomposti o combinati, come dare a+´invece di á. Mi chiedo come si possa tenerne conto, senza normalizzarlo.
siritinga

Se sei confuso con un numero enorme di risposte simili, controlla il mio benchmark .
Salvador Dali

Risposte:


94

In Go1 la runa è un tipo incorporato.

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

4
non puoi usare len () in Go per scoprire la lunghezza di una stringa / Array / Slice ecc ... Ecco perché? - len () in Go indica la dimensione dell'input in byte. Non corrisponde alla sua lunghezza. - Non tutte le rune di utf8 hanno le stesse dimensioni. Può essere 1, 2, 4 o 8. - È necessario utilizzare il metodo RuneCountInString del pacchetto unicode / ut8 per ottenere la lunghezza della runa.
Anvesh Checka

15
@ AnveshChecka, non è corretto. Vedere golang.org/pkg/builtin/#len - len () su una slice restituisce sicuramente il numero di elementi, non la dimensione in byte. Una fetta di rune è il modo corretto per farlo.
Chowey

3
@ рытфолд Questo non funziona con la combinazione di caratteri. Vedi play.golang.org/p/sBgZAV7gCb , il carattere di combinazione non viene scambiato con la sua base.
Chowey

53

Russ Cox, sulla mailing list golang-noci , suggerisce

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

20
Mi piace come ti costringono a pensare alle codifiche.
György Andrasek

10
fuori tema: perché è [golang-nuts] e non [go-nuts]?
Jimmy

2
Wow, come va la doppia assegnazione in retromarcia? Interessante. Ora, pensa a una stringa con un numero dispari di rune. Quello di mezzo riceve un trattamento speciale, con il risultato finale corretto dopo tutto. :) Una piccola ottimizzazione interessante a cui non avrei pensato subito.
Kissaki

4
Non capisco perché questa conversione in runa, perché no rune:=[]rune(input)?
siritinga

1
Non è necessario il primo ciclo per intervallo. output: = [] rune (input); n: = len (output) E non hai bisogno della runa = rune [0: n]
dvallejo

29

Funziona, senza dover perdere tempo con le funzioni:

func Reverse(s string) (result string) {
  for _,v := range s {
    result = string(v) + result
  }
  return 
}

6
Sebbene funzioni, poiché le stringhe sono immutabili, è molto inefficiente. Ho pubblicato una soluzione più efficiente.
peterSO

5
Questo è fin troppo facile da capire. Rendilo più difficile :-) (e, "più uno" per andare avanti)
Roboprog

2
Questa è la risposta migliore a meno che l'inversione delle stringhe non sia il tuo collo di bottiglia.
Banjocat

1
@dolmen - perché questo non dovrebbe gestire la combinazione di caratteri? un intervallo su una stringa restituisce una runa che è un punto di codice.
Stan R.

1
@StanR. Una runa non è un glifo. Un glifo può essere composto da più punti di codice / rune. Vedi reedbeta.com/blog/programmers-intro-to-unicode/#combining-marks L' inversione dei punti di codice collegherà i segni di combinazione a un diverso punto di codice di base.
dolmen

14

Funziona su stringhe Unicode considerando 2 cose:

  • range funziona sulla stringa enumerando i caratteri Unicode
  • la stringa può essere costruita da int slice in cui ogni elemento è un carattere Unicode.

Quindi eccolo:

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

Assegnerei i:=len(o)-1e poi piegherei il per in una singola riga for _, c:=range s { o[i--]=c; }. Amico che ODIO il per senza parentesi - è consentito:for(_, c:=range s) { o[i--]=c; }
Lawrence Dol

Potresti spiegare cosa fa _?
Lawrence Dol,

6
@Software_Monkey: o [i--] = c non è consentito in Go. - e ++ sono dichiarazioni, non espressioni. _ significa scartare (ignorare) quella variabile.
Randy Sugianto 'Yuku' il

1
con go 1.1+ restituisce un errore nella riga string ([] int), se invece [] viene usato il tipo rune per o, tutto funziona
Otuk

1
@yuku: Ancora fallisce su s: = "Les Mise \ u0301rables"
Stefan Steiger

13

Dai progetti di esempio Go: golang / example / stringutil / reverse.go , di 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)
}

Vai a Playground per invertire una stringa

Dopo aver invertito la stringa "bròwn", il risultato corretto dovrebbe essere "nwòrb", non "nẁorb".
Nota la tomba sopra la lettera o.


Per preservare Unicode combinando caratteri come "as⃝df̅" con il risultato inverso "f̅ds⃝a",
fare riferimento a un altro codice elencato di seguito:

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


2
Grazie per aver chiarito la differenza da stackoverflow.com/a/10030772/3093387 - sembra che queste due soluzioni differiscano nel modo in cui gestiscono stringhe come "bròwn".
josliber

Grazie per aver menzionato la soluzione Rosettacode che gestisce la combinazione di caratteri
dolmen

11

Ho notato questa domanda quando Simon ha pubblicato la sua soluzione che, poiché le stringhe sono immutabili, è molto inefficiente. Anche le altre soluzioni proposte sono difettose; non funzionano o sono inefficienti.

Ecco una soluzione efficiente che funziona, tranne quando la stringa non è valida UTF-8 o la stringa contiene caratteri combinati.

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

1
Anche la stringa di ritorno (rune) funziona.

3
@ Tommy: No, return string(runes)non funziona per tutti i casi.
peterSO

potresti spiegare un po 'di più il motivo? Ho fatto un breve programma e lì funziona, ma forse quei casi di cui parli non si attivano lì? play.golang.org/p/yk1sAwFjol

1
@Tommy: il tuo breve programma dimostra semplicemente che il carattere NUL è un NOP quando viene inviato a una stampante o un terminale. La funzione Reverse2 non riesce per le stringhe con codifica UTF-8 non ASCII. Ho rivisto il tuo breve programma in modo che sia un test valido: play.golang.org/p/Ic5G5QEO93
peterSO

Un'altra "soluzione" sbagliata che non gestisce correttamente la combinazione dei caratteri.
dolmen

9

Ci sono troppe risposte qui. Alcuni di loro sono chiari duplicati. Ma anche da quello di sinistra è difficile selezionare la soluzione migliore.

Quindi ho esaminato le risposte, buttato via quella che non funziona per Unicode e rimosso anche i duplicati. Ho confrontato i sopravvissuti per trovare il più veloce. Quindi ecco i risultati con l'attribuzione (se noti le risposte che ho perso, ma che vale la pena aggiungere, sentiti libero di modificare il benchmark):

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

Quindi ecco il metodo più veloce di 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)
}

Per qualche motivo non posso aggiungere un benchmark, quindi puoi copiarlo da PlayGround(non puoi eseguire test lì). Rinominalo ed eseguigo test -bench=.


Nessuna di queste "soluzioni" gestisce correttamente la combinazione dei segni .
dolmen

6

Ho scritto la seguente Reversefunzione che rispetta la codifica UTF8 e i caratteri combinati:

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

Ho fatto del mio meglio per renderlo il più efficiente e leggibile possibile. L'idea è semplice, attraversa le rune alla ricerca di personaggi combinati, quindi inverti le rune dei personaggi combinati sul posto. Una volta che li abbiamo coperti tutti, invertire anche le rune dell'intera stringa sul posto.

Diciamo che vorremmo invertire questa stringa bròwn. Il òè rappresentato da due rune, una per l' ounicode e una per questo unicode \u0301ache rappresenta la "tomba".

Per semplicità, rappresentiamo la stringa in questo modo bro'wn. La prima cosa che facciamo è cercare caratteri combinati e invertirli. Quindi ora abbiamo la stringa br'own. Infine, invertiamo l'intera stringa e finiamo con nwo'rb. Questo ci viene restituito comenwòrb

Puoi trovarlo qui https://github.com/shomali11/util se desideri utilizzarlo.

Ecco alcuni casi di test per mostrare un paio di scenari diversi:

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

3

Basandosi sul suggerimento originale di Stephan202 e sembra funzionare per le stringhe Unicode:

import "strings";

func Reverse( orig string ) string {
    var c []string = strings.Split( orig, "", 0 );

    for i, j := 0, len(c)-1; i < j; i, j = i+1, j-1 {
        c[i], c[j] = c[j], c[i]
    }

    return strings.Join( c, "" );
}

Alternativo, non utilizzando il pacchetto di stringhe, ma non 'unicode-safe':

func Reverse( s string ) string {
    b := make([]byte, len(s));
    var j int = len(s) - 1;
    for i := 0; i <= j; i++ {
        b[j-i] = s[i]
    }

    return string ( b );
}

+1. Che funzioni. Ma devo dire che è piuttosto strano (per ora) che la divisione e l'unione siano necessarie per un compito così semplice ...
Stephan202

@martin: scusa per quella modifica. Ho accidentalmente incollato la mia risposta aggiornata nella tua domanda ... mi vergogno molto .
Stephan202

@Stephan - nessun problema. Ho aggiunto una soluzione alternativa, basata sulla funzione Bytes del pacchetto stringhe.
martin clayton

@Nosradena: sono tornato indietro nello stesso minuto (sono rimasto sorpreso di vedere che Martin ha aggiornato la sua risposta esattamente con lo stesso testo che avevo appena scritto ... e poi mi sono reso conto;)
Stephan202

@martin: la seconda versione sembra migliore se me lo chiedi :)
Stephan202

3
//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

Utilizzo di stringhe Builder è circa 3 volte più veloce rispetto all'utilizzo della concatenazione di stringhe


1
Mi chiedo, perché questa domanda non ha voti positivi nonostante sia la risposta più accurata
Nilesh

3

Qui è abbastanza diverso, direi un approccio più funzionale, non elencato tra le altre risposte:

func reverse(s string) (ret string) {
    for _, v := range s {
        defer func(r rune) { ret += string(r) }(v)
    }
    return
}

Sono abbastanza sicuro che non sia la soluzione più veloce, ma mostra come la variabile di ritorno retviene mantenuta in chiusura per ulteriori elaborazioni, da ogni funzione di differimento.
Vladimir Bauer

Lento e non gestisce correttamente la combinazione dei caratteri.
dolmen

1
Non sono sicuro di quanto sia veloce, ma è bellissimo.
donatJ

Le prestazioni di questo possono essere migliorate in Go 1.14. Almeno le note di rilascio affermano di avere zero spese generali di differimento.
Vladimir Bauer

2

Questa è l'implementazione più veloce

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

Hai valutato le soluzioni prima di affermare che è l'implementazione più veloce?
Denys Séguret

si l'ho fatto, ecco perché è presente il codice BenchmarkReverse :). Tuttavia non ho più i risultati.
rmuller

Soluzione rapida, ma ancora sbagliata in quanto non gestisce correttamente la combinazione di caratteri.
dolmen

È vero come dice @dolmen che questo non gestisce la combinazione di caratteri? C'è una soluzione qui che lo fa?
geraldss

2

Questo codice conserva intatte le sequenze di combinazione dei caratteri e dovrebbe funzionare anche con un input UTF-8 non valido.

package stringutil
import "code.google.com/p/go.text/unicode/norm"

func Reverse(s string) string {
    bound := make([]int, 0, len(s) + 1)

    var iter norm.Iter
    iter.InitString(norm.NFD, s)
    bound = append(bound, 0)
    for !iter.Done() {
        iter.Next()
        bound = append(bound, iter.Pos())
    }
    bound = append(bound, len(s))
    out := make([]byte, 0, len(s))
    for i := len(bound) - 2; i >= 0; i-- {
        out = append(out, s[bound[i]:bound[i+1]]...)
    }
    return string(out)
}

Potrebbe essere un po 'più efficiente se le primitive unicode / norm consentissero l'iterazione attraverso i confini di una stringa senza allocare. Vedi anche https://code.google.com/p/go/issues/detail?id=9055 .


Non esiste un "input UTF-8 non valido" nei valori stringa: quando si converte da []bytea stringGo, sostituisce "input UTF-8 non valido" con un punto di codice valido \uFFFD.
dolmen

Non capisco il commento sopra. Stai dicendo che il comportamento di questo codice è sbagliato quando viene presentato con una stringa contenente UTF-8 non valido?
rog

No. Sto dicendo che l'UTF-8 non valido in un Go stringnon esiste. Ma può esistere in un file []byte.
dolmen

Una stringa Go può contenere esattamente tanto utf-8 non valido quanto un byte []. Ad esempio: play.golang.org/p/PG0I4FJfEN
rog

2

Se hai bisogno di gestire cluster grapheme, usa il modulo unicode o regexp.

package main

import (
  "unicode"
  "regexp"
)

func main() {
    str := "\u0308" + "a\u0308" + "o\u0308" + "u\u0308"
    println("u\u0308" + "o\u0308" + "a\u0308" + "\u0308" == ReverseGrapheme(str))
    println("u\u0308" + "o\u0308" + "a\u0308" + "\u0308" == ReverseGrapheme2(str))
}

func ReverseGrapheme(str string) string {

  buf := []rune("")
  checked := false
  index := 0
  ret := "" 

    for _, c := range str {

        if !unicode.Is(unicode.M, c) {

            if len(buf) > 0 {
                ret = string(buf) + ret
            }

            buf = buf[:0]
            buf = append(buf, c)

            if checked == false {
                checked = true
            }

        } else if checked == false {
            ret = string(append([]rune(""), c)) + ret
        } else {
            buf = append(buf, c)
        }

        index += 1
    }

    return string(buf) + ret
}

func ReverseGrapheme2(str string) string {
    re := regexp.MustCompile("\\PM\\pM*|.")
    slice := re.FindAllString(str, -1)
    length := len(slice)
    ret := ""

    for i := 0; i < length; i += 1 {
        ret += slice[length-1-i]
    }

    return ret
}

Vorrei darti 1'000 voti positivi. Tutte le altre implementazioni in questa pagina invertono una STRINGA in modo errato (una STRINGA NON è una sequenza di caratteri).
Stefan Steiger

Questo non funziona. Se si inverte due volte la stringa non si ottiene la stringa originale. La diaeresi combinata iniziale (\ u0308), utilizzata in questo esempio, si combina con i caratteri precedenti creando una doppia dieresi "a" quando invertita. Se l' stroutput è quotato, modifica la citazione iniziale!
Joshua Kolden

2

Puoi anche importare un'implementazione esistente:

import "4d63.com/strrev"

Poi:

strrev.Reverse("abåd") // returns "dåba"

O per invertire una stringa che include caratteri unicode che combinano:

strrev.ReverseCombining("abc\u0301\u031dd") // returns "d\u0301\u031dcba"

Queste implementazioni supportano il corretto ordinamento dei caratteri unicode multibyte e combing quando sono invertiti.

Nota: le funzioni di inversione delle stringhe integrate in molti linguaggi di programmazione non mantengono la combinazione e l'identificazione dei caratteri di combinazione richiede un tempo di esecuzione notevolmente maggiore.


1

Sicuramente non è la soluzione più efficiente in termini di memoria, ma per una soluzione sicura UTF-8 "semplice" quanto segue porterà a termine il lavoro e non romperà le rune.

È secondo me il più leggibile e comprensibile della pagina.

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

    return
}

1

I due metodi seguenti funzionano più velocemente della soluzione più veloce che conserva la combinazione di caratteri , anche se questo non vuol dire che mi manchi qualcosa nella mia configurazione di benchmark.

//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

Secondo metodo ispirato da questo

//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

Ecco cosa ti manca nel tuo benchmark: la tua soluzione è più veloce perché non preserva la combinazione di caratteri. È semplicemente ingiusto confrontarli.
dolmen

1

NOTA: questa risposta è del 2009, quindi probabilmente ci sono soluzioni migliori là fuori ormai.


Sembra un po '"indiretto" e probabilmente non molto efficiente, ma illustra come l'interfaccia di Reader può essere utilizzata per leggere dalle stringhe. Gli IntVector sembrano anche molto adatti come buffer quando si lavora con le stringhe utf8.

Sarebbe ancora più breve quando si tralascia la parte 'size' e l'inserimento nel vettore tramite Inserisci, ma immagino che sarebbe meno efficiente, poiché l'intero vettore deve essere spostato indietro di uno ogni volta che viene aggiunta una nuova runa .

Questa soluzione funziona sicuramente con i caratteri 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());
}

Perché aggiungi tutti quei punti e virgola finali?
Morteza R

@ olivier-mason È ora di imparare a conoscere gofmt quando si condivide il codice Go.
dolmen

1
Quella risposta era di otto anni fa.
Oliver Mason

@OliverMason Non è mai troppo tardi per correggere (o eliminare) una soluzione imperfetta.
dolmen

0

Una versione che penso funzioni su Unicode. È basato sulle funzioni 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);
}

0

rune è un tipo, quindi usalo. Inoltre, Go non utilizza il punto e virgola.

func reverse(s string) string {
    l := len(s)
    m := make([]rune, l)

    for _, c := range s {
        l--
        m[l] = c
    }
    return string(m)
}

func main() {
    str := "the quick brown 狐 jumped over the lazy 犬"
    fmt.Printf("reverse(%s): [%s]\n", str, reverse(str))
}

Ha usato il punto e virgola quando la domanda è stata pubblicata.
OneOfOne

Un'altra "soluzione" sbagliata che non gestisce correttamente la combinazione dei caratteri.
dolmen


0

Per stringhe semplici è possibile utilizzare tale costruzione:

func Reverse(str string) string {
    if str != "" {
        return Reverse(str[1:]) + str[:1]
    }
    return ""   
}

-1

Ecco un'altra soluzione:

func ReverseStr(s string) string {
    chars := []rune(s)
    rev := make([]rune, 0, len(chars))
    for i := len(chars) - 1; i >= 0; i-- {
        rev = append(rev, chars[i])
    }
    return string(rev)
}

Tuttavia, la soluzione di yazu sopra è più elegante poiché inverte la []runefetta in posizione.


-1

Ancora un'altra soluzione (tm):

package main 
import "fmt"

type Runes []rune

func (s Runes) Reverse() (cp Runes) {
    l := len(s); cp = make(Runes, l)
    // i <= 1/2 otherwise it will mess up with odd length strings
    for i := 0; i <= l/2; i++ { 
        cp[i], cp[l-1-i] = s[l-1-i], s[i] 
    }
    return cp
}

func (s Runes) String() string {
    return string(s)
}

func main() { 
    input := "The quick brown 狐 jumped over the lazy 犬 +odd" 
    r := Runes(input)
    output := r.Reverse()
    valid := string(output.Reverse()) == input
    fmt.Println(len(r), len(output), r, output.Reverse(), valid)
}

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

Produzione

Input: GO je úžasné!
Output: nsažú ej OG
PASS
ok      github.com/alesr/reverse-string 0.098s

Funziona se l'input è in NFC. Ma come la maggior parte delle altre soluzioni sbagliate qui, non funziona con la combinazione di personaggi.
dolmen

-1
    func reverseString(someString string) string {
        runeString := []rune(someString)
        var reverseString string
        for i := len(runeString)-1; i >= 0; i -- {
            reverseString += string(runeString[i])
        }
        return reverseString
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.