本文共 3048 字,大约阅读时间需要 10 分钟。
目录
请实现微信拼手气红包算法,输入红包总额,输出红包抽取后的数值序列,算法考虑公平性、随机性。题目答案要求:总和为金额数,个数为红包数,单个金额不小于0.01,取两位小数。
如果0.01 * 红包个数大于总金额,这种情况下钱不够分。
对每一个抢到的红包预先分配0.01元,分配后剩下的金额为:总金额 - 0.01 * 红包个数。利用循环将每一个红包随机的从剩下的金额池中选取一个随机数,将该随机数作为抢到的金额与预分配0.01相加即为最终的结果。
为了完全保证公平性,在返回最终序列之前,需要将序列打乱(因为在上述的随机从金额池抽取的过程中,会出现前几个红包将金额池瓜分完,导致后面的红包全部是0.01,因此不能保证绝对的公平)。
package mainimport ( "bufio" "fmt" "math/rand" "os" "strconv")func main() { reader := bufio.NewReader(os.Stdin) fmt.Print("请输入总金额:") amountBytes, _, _ := reader.ReadLine() amount, err := strconv.ParseFloat(string(amountBytes), 10) if err != nil { fmt.Println("请输入合法的总金额格式。") return } fmt.Print("请输入红包个数:") numberBytes, _, _ := reader.ReadLine() number, err := strconv.Atoi(string(numberBytes)) if err != nil { fmt.Println("请输入整数。") return } pool := amount - float64(number)*0.01 if pool < 0 { fmt.Println("红包不够分") return } pool = pool * 100 result := make([]float64, 0) for i := 0; i < number; i++ { if i == number-1 { packet := Decimal(pool*0.01 + 0.01) result = append(result, packet) continue } packet := rand.Intn(int(pool)) pool = pool - float64(packet) result = append(result, Decimal(float64(packet)*0.01+0.01)) } Suffix(&result) fmt.Println(result)}func Decimal(value float64) float64 { value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", value), 64) return value}func Suffix(list *[]float64) { length := len(*list) if length <= 1 { return } for i := 0; i < length; i++ { randIndex := rand.Intn(length) (*list)[i], (*list)[randIndex] = (*list)[randIndex], (*list)[i] }}
package mainimport ( "bufio" "fmt" "math/rand" "os" "strconv")func main() { // 从控制台读取总金额、红包个数 reader := bufio.NewReader(os.Stdin) fmt.Print("请输入总金额:") amountBytes, _, _ := reader.ReadLine() amount, err := strconv.ParseFloat(string(amountBytes), 10) if err != nil { fmt.Println("请输入合法的总金额格式。") return } fmt.Print("请输入红包个数:") numberBytes, _, _ := reader.ReadLine() number, err := strconv.Atoi(string(numberBytes)) if err != nil { fmt.Println("请输入整数。") return } // 为每一个红包预分配0.01元,然后将剩余的金额放入红包池中 pool := amount - float64(number)*0.01 if pool < 0 { fmt.Println("红包不够分") return } // 将红包池转换成以分为单位的数字 pool = pool * 100 // 为每一个红包分配随机的金额,随机数分布在 0 ~ pool result := make([]float64, 0) for i := 0; i < number; i++ { // 如果是最后一个红包,则将pool内的剩余金额全部分配 if i == number-1 { packet := Decimal(pool*0.01 + 0.01) result = append(result, packet) continue } packet := rand.Intn(int(pool)) pool = pool - float64(packet) result = append(result, Decimal(float64(packet)*0.01+0.01)) } // 打乱分配结果 Suffix(&result) fmt.Println(result)}// 将一个浮点数保留两位小数func Decimal(value float64) float64 { value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", value), 64) return value}// 打乱序列func Suffix(list *[]float64) { length := len(*list) if length <= 1 { return } for i := 0; i < length; i++ { randIndex := rand.Intn(length) (*list)[i], (*list)[randIndex] = (*list)[randIndex], (*list)[i] }}
转载地址:http://rdsoi.baihongyu.com/