गो में एक स्ट्रिंग को कैसे रिवर्स करें?


103

हम गो में एक साधारण स्ट्रिंग को कैसे उल्टा कर सकते हैं?


1
जहां तक ​​मैं समझता हूं, नीचे दिए गए समाधान पूर्वगामी या संयोजन पात्रों के साथ काम नहीं करते हैं, जैसे कि a+´इसके बजाय देना á। मुझे आश्चर्य है कि इसे सामान्य करने के बिना, इसे कैसे ध्यान में रखा जा सकता है।
सेप्टिंग

यदि आप समान उत्तरों की एक बड़ी संख्या के साथ भ्रमित हैं, तो मेरे बेंचमार्क की जांच करें
साल्वाडोर डाली

जवाबों:


94

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

4
आप एक स्ट्रिंग / ऐरे / स्लाइस आदि की लंबाई का पता लगाने के लिए गो में () का उपयोग नहीं कर सकते ... यहाँ क्यों है? - गो (में) का अर्थ है बाइट्स में इनपुट का आकार। यह अपनी लंबाई के अनुरूप नहीं है। - सभी utf8 के रन एक ही आकार के नहीं हैं। यह 1, 2, 4, या 8 में से एक हो सकता है - आपको रनवे की लंबाई प्राप्त करने के लिए यूनिकोड / ut8 पैकेज की विधि RuneCountInString का उपयोग करना चाहिए।
अनवेश चैक

15
@AnveshChecka, यह गलत है। देखें golang.org/pkg/builtin/#len - len () एक स्लाइस पर निश्चित रूप से तत्वों की संख्या देता है, बाइट्स में आकार नहीं। रनों का एक टुकड़ा इसे करने का सही तरीका है।
चौबे

3
@ рытфолд यह वर्णों के संयोजन के साथ काम नहीं करता है। Play.golang.org/p/sBgZAV7gCb देखें , इसके वर्ण के साथ संयोजन वर्ण स्वैप नहीं किया गया है।
चौबे

53

रॉल कॉक्स, गोलंग-नट्स मेलिंग सूची पर , सुझाव देते हैं

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
मुझे पसंद है कि वे आपको एनकोडिंग के बारे में सोचने के लिए कैसे मजबूर करते हैं।
ग्योर्गी एन्द्रसेक

10
ऑफ-टॉपिक: यह क्यों [गोलंग-नट्स] है न कि [गो-नट्स]?
जिमी

2
वाह, wtf डबल असाइनमेंट के साथ है जब उलट रहा है? दिलचस्प। अब, एक स्ट्रिंग के बारे में सोचो, जो असमान संख्या में है। बीच वाले को विशेष उपचार मिलता है, हालांकि सभी के बाद सही अंत-परिणाम। :) एक दिलचस्प थोड़ा अनुकूलन मैं अभी के बारे में सोचा नहीं होगा।
Kissaki

4
मुझे समझ में नहीं आता कि इस रूपांतरण को क्यों भागना है, क्यों नहीं rune:=[]rune(input)?
सिरिटिंग

1
आपको रेंज लूप के लिए पहले की आवश्यकता नहीं है। आउटपुट: = [] रूण (इनपुट); n: = len (आउटपुट) और आपको rune की जरूरत नहीं है = rune [0: n]
dvallejo

29

यह काम करता है, सभी कार्यों के बारे में mucking के बिना:

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

6
हालांकि, यह काम करता है, क्योंकि तार अपरिवर्तनीय हैं, यह बहुत अक्षम है। मैंने एक अधिक कुशल समाधान पोस्ट किया है।
पेट्रोएस

5
यह वह जगह है ज्यादा भी समझने में आसान। इसे कठिन बनायें :-) (और, इसके साथ होने के लिए "प्लस वन")
रोबोप्रोग

2
यह सबसे अच्छा जवाब है जब तक कि तारों को उलट देना आपकी अड़चन नहीं है।
बैंजोकेट

1
@ डोलमेन - यह पात्रों के संयोजन को क्यों नहीं संभालेगा? एक स्ट्रिंग पर एक सीमा एक रूण देता है जो एक कोडपॉइंट है।
स्टेन आर।

1
@StanR। एक रून एक ग्लिफ़ नहीं है। एक ग्लिफ़ को कई कोडपॉइंट / रनों से बनाया जा सकता है। देखें reedbeta.com/blog/programmers-intro-to-unicode/#combining-marks कोडपॉइंट्स को उलट देना अलग-अलग आधार कोड बिंदु के संयोजन के निशान को जोड़ देगा।
dolmen

14

यह 2 बातों पर विचार करके यूनिकोड स्ट्रिंग्स पर काम करता है:

  • रेंज यूनिकोड वर्णों की गणना करके स्ट्रिंग पर काम करती है
  • स्ट्रिंग का निर्माण इंट स्लाइस से किया जा सकता है जहां प्रत्येक तत्व एक यूनिकोड वर्ण है।

तो यहाँ यह जाता है:

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

मैं असाइन करूंगा i:=len(o)-1और फिर एक ही लाइन के लिए फोल्ड करूंगा for _, c:=range s { o[i--]=c; }। मैन आई हेट फॉर द फॉर बिना कोष्ठक - क्या इसकी अनुमति है:for(_, c:=range s) { o[i--]=c; }
लॉरेंस डोल

क्या आप बता सकते हैं कि _ क्या करता है?
लॉरेंस डॉल

6
@Software_Monkey: o [i--] = c को गो में अनुमति नहीं है। - और ++ कथन हैं, अभिव्यक्ति नहीं। _ का अर्थ है उस चर को छोड़ना (अनदेखा करना)।
रैंडी सुगियंटो 'युकू'

1
1.1+ के साथ यह स्ट्रिंग ([] int) लाइन में त्रुटि देता है, अगर इसके बजाय [] रूनी प्रकार का उपयोग ओ के लिए किया जाता है, तो सभी काम
ओटुक

1
@yuku: अभी भी विफल रहता है: = "लेस मिसे \ u0301rables"
स्टीफन स्टीगर

13

से golang / उदाहरण / stringutil / reverse.go: जाओ उदाहरण परियोजनाओं , एंड्रयू 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)
}

एक स्ट्रिंग रिवर्स करने के लिए खेल का मैदान जाओ

स्ट्रिंग "ब्रोवन" को उलटने के बाद, सही परिणाम "nwbrb" होना चाहिए, न कि "noror"।
पत्र ओ के ऊपर कब्र पर ध्यान दें।


यूनिकोड संयोजन जैसे कि "as Undf with" को उल्टे परिणाम "f̅dsica" के साथ संरक्षित
करने के लिए , कृपया नीचे सूचीबद्ध एक और कोड देखें:

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


2
से अंतर को स्पष्ट करने के लिए धन्यवाद stackoverflow.com/a/10030772/3093387 - ऐसा लगता है कि इन दो समाधान है कि वे कैसे की तरह "ब्राउन" तार संभाल में मतभेद है।
josliber

Rosettacode समाधान है कि हैंडल अक्षरों के संयोजन का उल्लेख करने के लिए धन्यवाद
dolmen

11

मैंने इस सवाल पर गौर किया जब साइमन ने अपना समाधान पोस्ट किया , जो कि तार अपरिवर्तनीय हैं, बहुत अक्षम है। अन्य प्रस्तावित समाधान भी त्रुटिपूर्ण हैं; वे काम नहीं करते हैं या वे अक्षम हैं।

यहां एक कुशल समाधान है जो काम करता है, सिवाय इसके जब स्ट्रिंग वैध यूटीएफ -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 犬")))
}

1
वापसी स्ट्रिंग (रन) के रूप में अच्छी तरह से काम करता है।

3
@ टॉमी: नहीं, return string(runes)सभी मामलों के लिए काम नहीं करता है।
पेट्रोएस

क्या आप कृपया थोड़ा और बता सकते हैं कि ऐसा क्यों है? मैंने एक छोटा कार्यक्रम बनाया और यह वहां काम करता है, लेकिन हो सकता है कि आप जिन मामलों के बारे में बात करते हैं, वे वहां ट्रिगर न हों? play.golang.org/p/yk1sAwFjol

1
@ टॉमी: आपका लघु कार्यक्रम केवल यह प्रदर्शित करता है कि एनयूएल चरित्र एक एनओपी है जब एक प्रिंटर या टर्मिनल पर भेजा जाता है। आपका Reverse2 फ़ंक्शन गैर-ASCII UTF-8 एन्कोडेड स्ट्रिंग्स के लिए विफल रहता है। मैंने आपके लघु कार्यक्रम को संशोधित किया है ताकि यह एक मान्य परीक्षण हो: play.golang.org/p/Ic5G5QEO93
peterSO

एक और गलत "समाधान" जो पात्रों को ठीक से संयोजित नहीं करता है।
dolmen

9

यहाँ बहुत सारे उत्तर हैं। उनमें से कुछ स्पष्ट डुप्लिकेट हैं। लेकिन बाएं से भी, सबसे अच्छा समाधान चुनना मुश्किल है।

तो मैं जवाबों के माध्यम से चला गया, उस एक को फेंक दिया जो यूनिकोड के लिए काम नहीं करता है और डुप्लिकेट को भी हटा दिया है। मैंने सबसे तेजी से खोजने के लिए बचे हुए लोगों को चिह्नित किया। इसलिए यहां पर परिणाम हैं (यदि आप उन उत्तरों को नोटिस करते हैं, जो मुझे याद थे, लेकिन जोड़ने लायक हैं, तो बेंचमार्क को संशोधित करने के लिए स्वतंत्र महसूस करें):

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=.


उन "समाधानों" में से कोई भी सही ढंग से अंकों के संयोजन को संभालता है।
dolmen

6

मैंने निम्नलिखित 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)
}

मैंने इसे यथासंभव कुशल और पठनीय बनाने की पूरी कोशिश की। विचार सरल है, संयुक्त वर्णों की तलाश में दौड़ के माध्यम से पार जाना है और फिर संयुक्त पात्रों के रन-इन को उल्टा करना है। एक बार जब हम उन सभी को कवर कर लेते हैं, तो पूरे स्ट्रिंग के रन-इन को भी इन-प्लेस कर देते हैं।

कहते हैं कि हम इस तार को उल्टा करना चाहेंगे 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")
}

3

Stephan202 के मूल सुझाव पर निर्माण, और यूनिकोड स्ट्रिंग्स के लिए काम करना प्रतीत होता है:

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

वैकल्पिक, स्ट्रिंग्स पैकेज का उपयोग नहीं, लेकिन 'यूनिकोड-सुरक्षित' नहीं:

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। यह काम करता है। लेकिन मुझे कहना होगा कि यह बल्कि (अभी के लिए) अजीब है कि इस तरह के एक सरल कार्य के लिए विभाजन और शामिल होना आवश्यक है ...
Stephan202

@ स्मार्टिन: उस संपादन के लिए खेद है। मैंने गलती से अपना अद्यतन उत्तर आपके प्रश्न में दे दिया ... मुझे बहुत शर्म आई
Stephan202

@ स्टेफ़न - कोई समस्या नहीं। मैंने स्ट्रिंग पैकेज बाइट्स फ़ंक्शन के आधार पर एक वैकल्पिक समाधान जोड़ा।
मार्टिन क्लेटन

@ नोसरडेना: मैं एक ही मिनट के भीतर वापस लुढ़क गया (मुझे यह देखकर आश्चर्य हुआ कि मार्टिन ने ठीक उसी पाठ के साथ अपना उत्तर अपडेट किया था जो मैंने अभी लिखा था ... और फिर यह मुझ पर
छा गया

@ स्मार्टिन: दूसरा संस्करण बेहतर लगता है अगर आप मुझसे पूछें :)
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

स्ट्रिंग्स का उपयोग करना। स्टड कॉन्टेनेशन का उपयोग करने की तुलना में ब्रैस्ट 3 गुना अधिक तेज है


1
मुझे आश्चर्य है, इस सवाल का सबसे सटीक उत्तर होने के बावजूद कोई उत्थान क्यों नहीं है
नीलेश

3

यहाँ बिलकुल अलग है, मैं कहूंगा कि अधिक कार्यात्मक दृष्टिकोण, अन्य उत्तरों के बीच सूचीबद्ध नहीं:

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

मुझे पूरा यकीन है कि यह सबसे तेज़ समाधान नहीं है, लेकिन यह दर्शाता है कि कैसे वापसी चर retको आगे के प्रसंस्करण के लिए बंद रखा जाता है, प्रत्येक डीफ़र फ़ंक्शन द्वारा।
व्लादिमीर बाउर

धीमा और ठीक से वर्णों को संयोजित नहीं करता है।
dolmen

1
मुझे यकीन नहीं है कि यह कितना तेज़ है, लेकिन यह सुंदर है।
21

गो 1.14 में इस एक के प्रदर्शन में सुधार किया जा सकता है। कम से कम जारी नोटों में डेफर के शून्य ओवरहेड होने का दावा किया गया है।
व्लादिमीर बाउर

2

यह सबसे तेज कार्यान्वयन है

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

क्या आपने दावा किया है कि यह सबसे तेज़ कार्यान्वयन है, इससे पहले कि आप इसका समाधान कर लें?
सेज्यूरेट

हाँ मैंने किया, यही कारण है कि बेंचमार्क रीवर्स कोड मौजूद है :)। हालाँकि मेरे पास अब परिणाम नहीं हैं।
17

तेजी से समाधान, लेकिन अभी भी गलत है क्योंकि यह पात्रों को ठीक से संयोजन नहीं करता है।
dolmen

क्या यह सच है जैसा कि @ डोलमेन कहते हैं कि यह पात्रों के संयोजन को नहीं संभालता है? क्या यहां कोई समाधान है जो करता है?
गेराल्ड्स

2

यह कोड वर्णों के संयोजन के अनुक्रम को बरकरार रखता है, और इसे अमान्य UTF-8 इनपुट के साथ भी काम करना चाहिए।

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

यह थोड़ा और अधिक कुशल हो सकता है यदि यूनिकोड / मानक प्राइमेटिव ने आवंटन के बिना एक स्ट्रिंग की सीमाओं के माध्यम से पुनरावृति की अनुमति दी। Https://code.google.com/p/go/issues/detail?id=9055 भी देखें


कोई इस तरह के "अवैध UTF-8 इनपुट" स्ट्रिंग मूल्यों में है: जब से परिवर्तित []byteकरने के लिए stringजाओ की जगह "अवैध UTF-8 इनपुट" मान्य कोडपॉइंट द्वारा \uFFFD
dolmen

मुझे उपरोक्त टिप्पणी समझ नहीं आ रही है। क्या आप कह रहे हैं कि अमान्य यूटीएफ -8 युक्त स्ट्रिंग के साथ प्रस्तुत किए जाने पर इस कोड का व्यवहार गलत है?
rog

नहीं, मैं कह रहा हूँ कि अवैध गो-रक्षा केंद्र 8 एक stringअस्तित्व में नहीं है। लेकिन यह एक में मौजूद हो सकता है []byte
डॉल्मेन

एक गो स्ट्रिंग एक [] बाइट के रूप में बिल्कुल अमान्य utf-8 हो सकता है। उदाहरण के लिए: play.golang.org/p/PG0I4FJfEN
rog

2

यदि आपको अंगूर के गुच्छों को संभालने की आवश्यकता है, तो यूनिकोड या रेगेक्स मॉड्यूल का उपयोग करें।

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
}

मैं आपको 1'000 अपवोट देना चाहूंगा। इस पृष्ठ पर अन्य सभी कार्यान्वयन गलत तरीके से एक STRING को रिवर्स करते हैं (एक STRING चार्ट का अनुक्रम नहीं है)।
स्टीफन स्टीगर

यह काम नहीं करता है। यदि आप स्ट्रिंग को डबल रिवर्स करते हैं तो आपको मूल स्ट्रिंग नहीं मिलती है। इस उदाहरण में उपयोग किया जाने वाला प्रमुख कॉम्बिनेशन डाइअरेसिस (\ u0308), पूर्ववर्ती वर्णों के साथ मिलकर एक डबल umlaut 'a' को उलट देता है। यदि strआउटपुट उद्धृत किया गया है तो यह अग्रणी उद्धरण को संशोधित करता है!
जोशुआ कोल्डन

2

आप एक मौजूदा कार्यान्वयन भी आयात कर सकते हैं:

import "4d63.com/strrev"

फिर:

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

या यूनिकोड संयोजन पात्रों सहित एक स्ट्रिंग को उलटने के लिए:

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

ये कार्यान्वयन यूनिकोड मल्टीबाइट के सही क्रम का समर्थन करता है और उलट होने पर वर्णों का संयोजन करता है।

नोट: कई प्रोग्रामिंग भाषाओं में अंतर्निहित स्ट्रिंग रिवर्स फ़ंक्शन संयोजन को संरक्षित नहीं करते हैं, और संयोजन पात्रों की पहचान करने के लिए काफी अधिक निष्पादन समय की आवश्यकता होती है।


1

यह निश्चय ही सबसे अधिक स्मृति कुशल समाधान नहीं है, लेकिन "सरल" UTF-8 सुरक्षित समाधान के लिए निम्न कार्य किया जाएगा और रनों को नहीं तोड़ा जाएगा।

यह मेरी राय में पृष्ठ पर सबसे अधिक पठनीय और समझने योग्य है।

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

    return
}

1

वर्णों के संयोजन को बनाए रखने वाले सबसे तेज़ समाधान की तुलना में निम्नलिखित दो विधियाँ तेज़ी से चलती हैं , हालांकि यह कहना नहीं है कि मुझे अपने बेंचमार्क सेटअप में कुछ याद आ रहा है।

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

दूसरी विधि से प्रेरित इस

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

यहां वह है जो आप अपने बेंचमार्क में गायब हैं: आपका समाधान तेज है क्योंकि यह वर्णों के संयोजन को संरक्षित नहीं करता है। उनकी तुलना करना अनुचित है।
डॉल्मेन

1

नोट: यह उत्तर 2009 से है, इसलिए अब तक बेहतर समाधान हैं।


थोड़ा सा 'गोल चक्कर' दिखता है, और शायद बहुत कुशल नहीं है, लेकिन यह बताता है कि स्ट्रिंग्स से पढ़ने के लिए रीडर इंटरफ़ेस का उपयोग कैसे किया जा सकता है। जब utf8 तार के साथ काम कर रहे हो तो IntVector भी बफ़र के रूप में बहुत उपयुक्त लगते हैं।

'आकार ’वाले हिस्से को छोड़ते समय यह और भी छोटा होगा, और सम्मिलित रूप से वेक्टर में सम्मिलन होगा, लेकिन मुझे लगता है कि यह कम कुशल होगा, क्योंकि पूरे वेक्टर को फिर एक बार नया रन जोड़ने पर एक बार वापस धकेलने की आवश्यकता होती है। ।

यह समाधान निश्चित रूप से 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());
}

आप उन सभी अनुगामी अर्धविरामों को क्यों जोड़ते हैं?
मोर्टिजा आर

@ ओलिवियर-मेसन गो कोड साझा करते समय गोफ़्ट के बारे में जानने का समय है।
डॉल्मेन

1
वह उत्तर आठ साल पहले का था।
ओलिवर मेसन

@OliverMason एक अपूर्ण समाधान को ठीक करने (या हटाने) के लिए कभी भी देर नहीं हुई है।
dolmen

0

एक संस्करण जो मुझे लगता है कि यूनिकोड पर काम करता है। यह utf8.une फ़ंक्शन पर बनाया गया है:

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

रूण एक प्रकार है, इसलिए इसका उपयोग करें। इसके अलावा, गो अर्धविराम का उपयोग नहीं करता है।

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

जब यह प्रश्न पोस्ट किया गया था, तो उसने अर्धविराम का इस्तेमाल किया था।
वनऑफने

एक और गलत "समाधान" जो पात्रों को ठीक से संयोजित नहीं करता है।
dolmen

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


0

सरल तारों के लिए इस तरह के निर्माण का उपयोग करना संभव है:

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

-1

यहाँ अभी तक एक और समाधान है:

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

हालाँकि, ऊपर यजु का समाधान अधिक सुरुचिपूर्ण है क्योंकि वह []runeजगह में स्लाइस को उलट देता है।


-1

अभी तक एक और समाधान (टीएम):

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

परीक्षा

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

उत्पादन

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

यह काम करता है यदि इनपुट एनएफसी में है। लेकिन ज्यादातर अन्य गलत समाधानों के रूप में यह वर्णों के संयोजन के साथ काम नहीं करता है।
डोलमेन

-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
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.