Last active
April 16, 2018 12:28
-
-
Save toVersus/1d41bac213f283f67ed8e8ad859cf710 to your computer and use it in GitHub Desktop.
[Language Processing 100 Essentials] #0: Reverse a string
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
} | |
} | |
} |
Author
toVersus
commented
Feb 5, 2018
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment