Reverse string in Golang

Reverse string in Golang

In this article you'll get to know the multiple ways in you can reverse a string in Go

In this article you’ll learn about how you can reverse a string using multiple ways in Golang, as of now in Golang, there is no built-in method to reverse a string yet, so we will create our function to reverse a string.

In Golang, a string is a sequence of UTF-8 bytes. According to the UTF-8 encoding standard, ASCII characters are single-byte. However, other characters range between 1 and 4 bytes, because of this inconsistency, it is nearly impossible to index a specific character inside a string.

If we want to index a character in Golang, we can convert a string to an array or rune. A rune is a Unicode point. A Unicode point refers to a numerical value representing a Unicode character.

Ways to reverse a string in Golang

Below is all ways to reverse a string in Golang:

  • Simply append string.

  • Reverse a string — Rune by Rune.

  • Reverse a String — Swap Left Rune with Right.

  • From the right side.

These are the all possible implementations you will see in the action below, so without taking any extra time let’s see the implementations one by one.

1. Simply append a string

This example declares an empty string and then starts appending the characters from the end, one by one.

1. Algorithm:

Let’s go through the approach to solving this problem first.

  • Step 1: Define a function that accepts a string as a parameter.

  • Step 2: Iterate over the input string and prepend the characters one by one to the resultant string.

  • Step 3: Return the resultant string.

Code:

Below is the code of the following way:

package main

import (
    "fmt"
)

// approach 1
// function, which takes a string as
// argument and return the reversed string.
func reverse(s string) string {
    var str string
    for _, v := range s {
        str = string(v) + str
    }
    return str
}

func main() {
    s := "programmingeeksclub"
    fmt.Println("original string:", s)
    r := reverse(s)
    fmt.Println("reversed string:", r)
}

Explanation:

  • Line 10–15: We created a reverse() function, The function accepts a string as a parameter, iterates over it, and prepends each character to a str variable which is a type string. At the end of the reverse function, it returns the str variable with reversed string.

  • Line 19: We declared a string variable named s inside the main() function.

  • Line 20: We are printing the s variable which is not yet reversed.

  • Line: 21: We called the reverse() function and passed the s variable to the reverse() function and we stored the returned value from the reverse() to the r variable.

  • Line 22: We output the result of the reversed string on the console.

Below is the output of the following code:

$ go run main.go
original string: programmingeeksclub
reversed string: bulcskeegnimmargorp

Reversing a string by character is very similar to the process to reverse an array. The difference is that strings are immutable in Go. Therefore, we must first convert the string to a mutable array of runes ([]rune), perform the reverse operation on that, and then re-cast to a string and return the reversed string.

2. Reverse a string — Rune by Rune

This example first appends the provided string to the rune variable and then declares another variable type rune to store the reversed characters one by one.

Algorithm:

Let’s go through the approach to solving this problem.

  • Step 1: Define a function named reverse that accepts a string as a parameter.

  • Step 2: Declare a variable type []rune and initialize the parameter value into []rune variable, like this []rune(parameter).

  • Step 3: Declare another variable of type []rune, this variable will have our reversed characters and will be used to return reversed string.

  • Step 4: Iterate over in reverse on the input runes(step 2) and append the characters one by one to the resultant rune variable(step 3).

  • Step 5: Convert step 3 []rune to string and return the result as a string.

Code:

Below is the code in the following way:

package main

import (
    "fmt"
)

// approach 2
// function, which takes a string as
// argument and return the reversed string.
func reverse(s string) string {
    rune_arr := []rune(s)
    var rev []rune
    for i := len(rune_arr) - 1; i >= 0; i-- {
        rev = append(rev, rune_arr[i])
    }
    return string(rev)
}

func main() {
    s := "programmingeeksclub"
    fmt.Println("original string:", s)
    r := reverse(s)
    fmt.Println("reversed string:", r)
}

Explanation:

  • Line 10–16: We created a function called reverse(), The function accepts a string as a parameter(argument), then we declared a rune_arr type []rune variable and at the same time passed the value of the parameter to rune_arr, in next step, we declared rev variable of type []rune, iterates over rune_arr in reverse, and appends each character to rev variable which is of type rune. At the end of the reverse function, before returns it converts the rev variable into a string and then returns with reversed string.

  • Line 20: We declared a string variable named s inside the main() function.

  • Line 21: We are printing the s variable which is not yet reversed.

  • Line: 22: We called the reverse() function and passed the s variable to the reverse() function and we stored the returned value from reverse() to the r variable.

  • Line 23: We output the result of the reversed string on the console.

Below is the output of the following code:

$ go run main.go
original string: programmingeeksclub
reversed string: bulcskeegnimmargorp

3. Reverse a String — Swap Left Rune with the Right

This example simply first appends the provided string to the rune variable and then iterates over the slice of rune and swaps each left index with right characters one by one and returns the reversed rune as a string.

Algorithm:

Let’s go through the approach to solving this problem.

  • Step 1: Define a function named reverse that accepts a string as a parameter.

  • Step 2: Declare a variable type []rune and initialize the parameter value into []rune variable, like this []rune(parameter).

  • Step 3: Iterate over the input runes(step 2) and swap the characters one by one from left to right.

  • Step 4: Convert step 2 []rune to string and return the result as a string.

Code:

Below is the code in the following way:

package main

import (
    "fmt"
)

// approach 3
// function, which takes a string as
// argument and return the reverse of string.
func reverse(s string) string {
    rns := []rune(s)
    for i, j := 0, len(rns)-1; i < j; i, j = i+1, j-1 {
        rns[i], rns[j] = rns[j], rns[i]
    }
    return string(rns)
}

func main() {
    s := "https://programmingeeksclub.com/"
    fmt.Println("original string:", s)
    r := reverse(s)
    fmt.Println("reversed string:", r)
}

Explanation:

  • Line 10–15: We created a reverse() function, The function accepts a string as a parameter, declares an rns type []rune variable and at the same time passes the value of the parameter to rns, iterates over it, and swaps characters one by one. At the end of the reverse function, it returns the rns variable, but before we’re converting a slice of rune back to string then returning with reversed string.

  • Line 19: We declared a string variable named s inside the main() function.

  • Line 20: We are printing the s variable which is not yet reversed.

  • Line: 21: We called the reverse() function and passed the s variable to the reverse() function and we stored the returned value from reverse() to the r variable.

  • Line 22: We output the result of the reversed string on the console.

Below is the output of the following code:

$ go run main.go
original string: https://programmingeeksclub.com/
reversed string: /moc.bulcskeegnimmargorp//:sptth

4. From the right side

This example declares an empty string and then starts appending the characters from the last index, one by one.

Algorithm:

Let’s go through the approach to solving this problem first.

  • Step 1: Define a function that accepts a string as a parameter.

  • Step 2: Declare a string builder type variable to hold the reversed string.

  • Step 3: Iterate over the input string and prepend the characters one by one from the last index to the first, into the resultant string.

  • Step 4: Return the resultant string.

Code:

Below is the code in the following way:

package main

import (
    "fmt"
    "strings"
)

// approach 4
// function, which takes a string as
// argument and return the reverse of string.
func reverse(s string) string {
    var str strings.Builder
    str.Grow(len(s) - 1)
    for idx := range s {
        str.Write(([]byte{s[(len(s)-1)-idx]}))
    }
    return str.String()
}

func main() {
    s := "https://dailynews.programmingeeksclub.com/"
    fmt.Println("original string:", s)
    r := reverse(s)
    fmt.Println("reversed string:", r)
}

Now one thing comes to mind why I used strings.Builder type here instead of a string, well strings.Builder does concatenation faster than using += for string.

Explanation:

  • Line 11–17: We created a reverse() function, The function accepts a string as a parameter, iterates over it, and appends each character to an str variable which is type strings.Builder. At the end of the reverse function, it returns the str variable with reversed string.

  • Line 21: We declared a string variable named s inside the main() function.

  • Line 22: We are printing the s variable which is not yet reversed.

  • Line: 23: We called the reverse() function and passed the s variable to the reverse() function and we stored the returned value from reverse() to the r variable.

  • Line 24: We output the result of the reversed string on the console.

Below is the output of the following code:

$ go run main.go
original string: https://dailynews.programmingeeksclub.com/
reversed string: /moc.bulcskeegnimmargorp.swenyliad//:sptth

There are many more ways to reverse a string in Golang, I’ll leave others to you, write some code, and you can send your code to us as well if you want your code to be feature in this article, what do you have to do is just write your code and explain in the way I have done in this article.

Now let’s see some benchmark results of the mentioned ways which one is the fastest one to use in your production code.

Benchmark

Create a file called main_test.go and paste the following code into it.

package main

import (
    "strings"
    "testing"
)

func SimpleReverse(s string) string {
    var str string
    for _, v := range s {
        str = string(v) + str
    }
    return str
}

// Benchmark
// goos: windows
// goarch: amd64
// pkg: reverse_string
// cpu: Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz
// BenchmarkSimpleReverse-6                     636098          1727 ns/op        1088 B/op          42 allocs/op

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

// Benchmark
// goos: windows
// goarch: amd64
// pkg: reverse_string
// cpu: Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz
// BenchmarkSwapReverse-6                      3002754           401.2 ns/op         224 B/op           2 allocs/op

func UsingStrBuilderToReverse(s string) string {
    var str strings.Builder
    str.Grow(len(s) - 1)
    for idx := range s {
        str.Write(([]byte{s[(len(s)-1)-idx]}))
    }
    return str.String()
}

// Benchmark
// goos: windows
// goarch: amd64
// pkg: reverse_string
// cpu: Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz
// BenchmarkUsingStrBuilderToReverse-6         7319005           166.3 ns/op         144 B/op           2 allocs/op

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

// Benchmark
// goos: windows
// goarch: amd64
// pkg: reverse_string
// cpu: Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz
// BenchmarkRunesReverse-6                     1798329           677.3 ns/op         728 B/op           8 allocs/op

func ReadFromRightReverse(s string) string {
    r := make([]byte, len(s))
    for i := 0; i < len(s); i++ {
        r[i] = s[len(s)-1-i]
    }
    return string(r)
}

// Benchmark
// goos: windows
// goarch: amd64
// pkg: reverse_string
// cpu: Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz
// BenchmarkReadFromRightReverse-6            14868045            81.20 ns/op          96 B/op           2 allocs/op

func ReadFromRightBytesReverse(s string) string {
    var byte strings.Builder
    byte.Grow(len(s))
    for i := len(s) - 1; i >= 0; i-- {
        byte.WriteByte(s[i])
    }
    return byte.String()
}

// Benchmark
// goos: windows
// goarch: amd64
// pkg: reverse_string
// cpu: Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz
// BenchmarkReadFromRightBytesReverse-6       13467786            88.55 ns/op          48 B/op           1 allocs/op

func BenchmarkSimpleReverse(b *testing.B) {
    for i := 0; i < b.N; i++ {
        s := "https://dailynews.programmingeeksclub.com/"
        SimpleReverse(s)
    }
}

func BenchmarkSwapReverse(b *testing.B) {
    for i := 0; i < b.N; i++ {
        s := "https://dailynews.programmingeeksclub.com/"
        SwapReverse(s)
    }
}

func BenchmarkUsingStrBuilderToReverse(b *testing.B) {
    for i := 0; i < b.N; i++ {
        s := "https://dailynews.programmingeeksclub.com/"
        UsingStrBuilderToReverse(s)
    }
}

func BenchmarkRunesReverse(b *testing.B) {
    for i := 0; i < b.N; i++ {
        s := "https://dailynews.programmingeeksclub.com/"
        RunesReverse(s)
    }
}

func BenchmarkReadFromRightReverse(b *testing.B) {
    for i := 0; i < b.N; i++ {
        s := "https://dailynews.programmingeeksclub.com/"
        ReadFromRightReverse(s)
    }
}

func BenchmarkReadFromRightBytesReverse(b *testing.B) {
    for i := 0; i < b.N; i++ {
        s := "https://dailynews.programmingeeksclub.com/"
        ReadFromRightBytesReverse(s)
    }
}

Now run the go test -bench=. command.

reverse string benchmark results.png

As you can see the fastest reverse string way took 82.64ns and while the lowest took 1742 ns.

Fastest Way

Below is the fastest way between all mentioned ways.

func ReadFromRightReverse(s string) string {
    r := make([]byte, len(s))
    for i := 0; i < len(s); i++ {
        r[i] = s[len(s)-1-i]
    }
    return string(r)
}

This article is originally posted on programmingeeksclub.com

My Blogging Website : Programming Geeks Club

My Facebook Page: Programming Geeks Club

My Telegram Channel: Programming Geeks Club

My Twitter Account: Kuldeep Singh

My Youtube Channel: Programming Geeks Club