楔子
學習《go語言程序設計》 所做的筆記
5 過程式編程
5.6.4 遞歸函數|迴文
書中這段判斷一個字符串是否是迴文感覺代碼寫的特別好,因此做個記錄,受到這個啓發,寫了字符串反轉的例子
// 使用遞歸判斷是否是迴文
func IsPlindrome(word string) bool {
//獲取字符串長度|(len函數獲取的字符串字節數)
if utf8.RuneCountInString(word) <= 1 {
return true
}
//返回字符串的第一個字符(rune類型)和它佔用的字節數
first, sizeOfFirst := utf8.DecodeRuneInString(word)
last, sizeOfLast := utf8.DecodeLastRuneInString(word)
if first != last {
return false
}
return IsPlindrome(word[sizeOfFirst : len(word)-sizeOfLast])
}
函數的第一部分是一個跳出條件:如果單詞的長度爲0或者1,那麼就認爲這是一個迴文。函數整體算法時比較首字母和尾字母,如果不同,不是迴文返回false。如果相同,就遞歸判斷這個單詞的一個字串
當一個函數使用尾遞歸(最後執行一句遞歸調用),這種情況可以簡單地 將他轉換成一個循環,使用循環的好處是可以
減少遞歸調用的開銷,因爲有限的空間棧對函數的深度遞歸是很有影響的。
受到上面啓發,寫的字符串反轉函數
//受到上面判斷迴文寫的字符串反轉
func MyReverse(str string) string {
strSlice := make([]rune, 0)
for len(str)>0 {
sts, sizeOfLast := utf8.DecodeLastRuneInString(str)
strSlice = append(strSlice, sts)
//截取掉最後一個字符
str = str[:len(str)-sizeOfLast]
}
return string(strSlice)
}
"github.com/huandu/xstrings"中字符串反轉
// Reverse a utf8 encoded string.
func Reverse(str string) string {
var size int
tail := len(str)
buf := make([]byte, tail)
s := buf
for len(str) > 0 {
_, size = utf8.DecodeRuneInString(str)
tail -= size
s = append(s[:tail], []byte(str[:size])...)
str = str[size:]
}
return string(buf)
}