package main
import "fmt"
func Reverse(str string) string {
r := ""
for i := len(str) - 1; i >= 0; i-- {
r = string(str[i])
// fmt.Println(r)
}
return r
}
func Generate(str string) string {
str = Reverse(str)
// vowel := ""
for _, rne := range str {
if rne == 'a' {
str = "A"
}
if rne == 'e' {
str = "E"
}
if rne == 'i' {
str = "I"
}
if rne == 'o' {
str = "O"
}
if rne == 'u' {
str = "U"
}
}
return Reverse(str)
}
func main() {
fmt.Println(...("haigolang123"))
}
This program will accept a logic from the previous function, then combine it with the next function. I wondering how to invoke a function from the result of another function. expect output is "321gnAlOgIAh"
CodePudding user response:
I didn't get why you are trying to reverse the string twice if your input is haigolang123 and expected output is 321gnAlOgIAh. Let's refactor step by step.
- For vowels, if all you needed to do is convert lower case to upper, you can direct subtract number 32 from rune (since 'a'=97 & 'A'=65). So, use a function to common out the check.
func in(c rune, list []rune) bool {
for _, l := range list {
if c == l {
return true
}
}
return false
}
This can check as follows:
vowelsLower := []rune{'a', 'e', 'i', 'o', 'u'}
# Some code here
if in(c, vowelsLower) {
result = string(c-32)
}
- There are many ways to append strings, refer here when working particularly with strings. However, we are working with runes. It is easier to append it to a byte slice. Looking at the bigger picture, []byte can be directly converted to string when needed.
var result []byte
# Some code here
if in(c, vowelsLower) {
result = append(result, byte(c-diff))
}
While returning,
return string(result)
This is your code with these changes.
- Additionally, why to iterate twice (once in
Generate, and again inReverse). Try reverse iterating and do the vowel case switching. The noticeable difference of this approach is it uses bytes directly.
Range over string gives
rune. Slicing the string givesbyte. Of course they can be typecasted from one another.
Since we were already using bytes in previous approach, the code looks like this.
Happy coding!!
CodePudding user response:
In Go, write
package main
import "fmt"
func toUpper(r rune) rune {
switch r {
case 'a', 'e', 'i', 'o', 'u':
r &= 0b1101_1111
}
return r
}
func Generate(s string) string {
g := []rune(s)
for i, j := 0, len(g)-1; i <= j; i, j = i 1, j-1 {
g[i], g[j] = toUpper(g[j]), toUpper(g[i])
}
return string(g)
}
func main() {
s := "haigolang123"
fmt.Printf("%q\n", s)
g := Generate(s)
fmt.Printf("%q\n", g)
}
https://go.dev/play/p/pGRas6qsi8O
"haigolang123"
"321gnAlOgIAh"
Go is designed for efficient solutions.
In Go, strings are immutable. concatenating strings a and b creates a new string of length len(a) len(b) and copies both a and b to the new string. It can get expensive.
Testing characters for all the vowels, even after you have matched one, is unnecessary.
Refactor your functional decomposition of Generate to include reversing a string while using a toUpper function for vowels.
