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)
}

# 代碼解釋:

代碼的含義其中大部分地方都做了詳細的解釋,所以最後這地方只做簡單的說明:

  1. 關於每個名字中我使用了map的方式,除了map使用switch-case也是可以的,方式有很多,個人認為這樣比較直觀而已
  2. 如果不需要知道每個人獲得的金幣數量,只需要知道最終剩下的金幣數量,那麼可以將letters的聲明放在循環外,執行效率會更高
  3. 由於GO語言沒有內置清空map的函數,所以無法快速清空map,但是考慮GO語言的並發特性,垃圾回收效率未必會比清空函數效率低.
  4. 可以將字母與分配金幣的數量放到另一個map中,這樣到有新的字母進來需要分配金幣的時候就可以很快的解決,而不必修改後續代碼.
上一篇:二分查找及其变种


下一篇:寻找比目标字母大的最小字母