golang解決分金幣問題
# 題目:
你有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中,這樣到有新的字母進來需要分配金幣的時候就可以很快的解決,而不必修改後續代碼.
浙公网安备 33010602011771号