# 題目:
你有50枚金币,需要分配给以下几个人:Matthew,Sarah,Augustus,Heidi,Emilie,Peter,Giana,Adriano,Aaron,Elizabeth。
分配规则如下:
a. 名字中每包含1个'e'或'E'分1枚金币
b. 名字中每包含1个'i'或'I'分2枚金币
c. 名字中每包含1个'o'或'O'分3枚金币
d: 名字中每包含1个'u'或'U'分4枚金币
写一个程序,计算每个用户分到多少金币,以及最后剩余多少金币?
程序结构如下,请实现 ‘dispatchCoin’ 函数
var ( coins = 50 users = []string{ "Matthew", "Sarah", "Augustus", "Heidi", "Emilie", "Peter", "Giana", "Adriano", "Aaron", "Elizabeth", } distribution = make(map[string]int, len(users)) ) func main() { left := dispatchCoin() fmt.Println("剩下:", left) }
# 實現代碼:
package main import "fmt" var ( coins = 50 users = []string{ "Matthew", "Sarah", "Augustus", "Heidi", "Emilie", "Peter", "Giana", "Adriano", "Aaron", "Elizabeth", } distribution = make(map[string]int, len(users)) ) func dispatchCoin() int { // 計算每個人名字中擁有可以分配金幣的字母數量 for _, user := range users { // 定義一個字母與數量的映射,由於go語言沒有清空map的函數,所以每次循環的時候都make一個新的空間效率更高 letters := make(map[rune]int, 36) // 獲得每個人名字中每個字母的數量 for _, letter := range user { // 出現一個新字母就添加到map當中,出現已有的字母就在原有基礎上+1 letters[letter]++ } // 計算每個人會獲得的硬幣 distribution[user] = (letters['e'] + letters['E']) + (letters['i']+letters['I'])*2 + (letters['o']+letters['O'])*3 + (letters['u']+letters['U'])*4 // 支付當前用戶應該獲得的金幣 coins -= distribution[user] } return coins } func main() { left := dispatchCoin() fmt.Println("剩下:", left) fmt.Println("每個用戶獲得的金幣: ", distribution) }
# 代碼解釋:
代碼的含義其中大部分地方都做了詳細的解釋,所以最後這地方只做簡單的說明:
- 關於每個名字中我使用了map的方式,除了map使用switch-case也是可以的,方式有很多,個人認為這樣比較直觀而已
- 如果不需要知道每個人獲得的金幣數量,只需要知道最終剩下的金幣數量,那麼可以將letters的聲明放在循環外,執行效率會更高
- 由於GO語言沒有內置清空map的函數,所以無法快速清空map,但是考慮GO語言的並發特性,垃圾回收效率未必會比清空函數效率低.
- 可以將字母與分配金幣的數量放到另一個map中,這樣到有新的字母進來需要分配金幣的時候就可以很快的解決,而不必修改後續代碼.