Skip to content

Instantly share code, notes, and snippets.

@toVersus
Last active April 16, 2018 12:28
Show Gist options
  • Save toVersus/1d41bac213f283f67ed8e8ad859cf710 to your computer and use it in GitHub Desktop.
Save toVersus/1d41bac213f283f67ed8e8ad859cf710 to your computer and use it in GitHub Desktop.
[Language Processing 100 Essentials] #0: Reverse a string
package main
import (
"bufio"
"fmt"
"os"
"reflect"
"strings"
)
func main() {
buf := *reverseByDeferStringBuilder("stressed")
fmt.Printf("%+v\n", buf.String())
}
// reverseStringRecursively rearranges the elements of byte slice in reverse order streamingly
func reverseStringRecursively(b []byte) []byte {
if len(b) == 0 {
return b
}
return append(reverseStringRecursively(b[1:]), b[0])
}
// reverseBySwapper rearranges the elements of slice from tail to head by using swapper
func reverseBySwapper(slice interface{}) {
t := reflect.ValueOf(slice)
swap := reflect.Swapper(slice)
l := t.Len()
for i := 0; i < l/2; i++ {
swap(i, l-i-1)
}
}
// reverseBySelfImplSwapper reverses input string just by using for-loop self implementation
func reverseBySelfImplSwapper(s string) string {
t := strings.Split(s, "")
l := len(t)
for i := 0; i < l/2; i++ {
t[i], t[l-i-1] = t[l-i-1], t[i]
}
return strings.Join(t, "")
}
// reverseByDefer outputs reversed string by using defer's Last in First Out order characteristics
func reverseByDefer(str string) {
writer := bufio.NewWriter(os.Stdout)
for _, s := range str {
defer writer.Flush()
defer fmt.Fprint(writer, string(s))
}
}
// reverseByDeferStringBuilder returns the reversed string within string builder
// by using defer's Last in First Out order characteristics
func reverseByDeferStringBuilder(str string) *strings.Builder {
var buf strings.Builder
for _, s := range str {
defer fmt.Fprint(&buf, string(s))
}
return &buf
}
package main
import (
"reflect"
"testing"
)
var reverseTests = []struct {
name string
str string
expect string
}{
{
name: "should return byte array in reverse order",
str: "stressed",
expect: "desserts",
},
}
func TestReverseStringRecursively(t *testing.T) {
for _, testcase := range reverseTests {
t.Log(testcase.name)
b := []byte(testcase.str)
if result := reverseStringRecursively(b); !reflect.DeepEqual(string(result), testcase.expect) {
t.Errorf("result => %s\n expect => %s\n", result, testcase.expect)
}
}
}
func TestReverseBySwapper(t *testing.T) {
for _, testcase := range reverseTests {
t.Log(testcase.name)
result := []byte(testcase.str)
if reverseBySwapper(result); !reflect.DeepEqual(string(result), testcase.expect) {
t.Errorf("result => %s\n expect => %s\n", string(result), testcase.expect)
}
}
}
func TestReverseBySelfImplSwapper(t *testing.T) {
for _, testcase := range reverseTests {
t.Log(testcase.name)
if result := reverseBySelfImplSwapper(testcase.str); !reflect.DeepEqual(result, testcase.expect) {
t.Errorf("result => %s\n expect => %s\n", result, testcase.expect)
}
}
}
func BenchmarkReverseStringRecursively(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, testcase := range reverseTests {
b := []byte(testcase.str)
reverseStringRecursively(b)
}
}
}
func BenchmarkReverseBySwapper(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, testcase := range reverseTests {
b := []byte(testcase.str)
reverseBySwapper(b)
}
}
}
func BenchmarkReverseBySelfImplSwapper(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, testcase := range reverseTests {
reverseBySelfImplSwapper(testcase.str)
}
}
}
func BenchmarkReverseByDeferStringBuilder(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
for _, testcase := range reverseTests {
buf := *reverseByDeferStringBuilder(testcase.str)
buf.String()
}
}
}
@toVersus
Copy link
Author

toVersus commented Feb 4, 2018

not supporting DBCH string

@toVersus
Copy link
Author

toVersus commented Feb 5, 2018

PS> go test -bench . --benchmem
goos: windows
goarch: amd64
pkg: github.com/toversus/language-processing/0-reverse-byte-array
BenchmarkReverseByAppend-8                      20000000                75.6 ns/op            16 B/op          2 allocs/op
BenchmarkReverseBySwap-8                        20000000               165 ns/op              72 B/op          3 allocs/op
BenchmarkReverseBySelfSwap-8                     5000000               305 ns/op             144 B/op          3 allocs/op
BenchmarkReverseByDeferStringBuilder-8           1000000              1718 ns/op             328 B/op         26 allocs/op
PASS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment