博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
微信拼手气红包实现(Go,腾讯面试题)
阅读量:4189 次
发布时间:2019-05-26

本文共 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/

你可能感兴趣的文章
一篇文章看懂ZooKeeper内部原理
查看>>
全面理解Java内存模型
查看>>
Java类型信息详解
查看>>
深入理解Java线程池
查看>>
Java线程堆栈分析
查看>>
Java中子类能否继承父类的私有属性和方法
查看>>
JVM内存模型详解
查看>>
(二)Git--工作区和暂存区、管理修改与撤销
查看>>
(七)Git--自定义Git
查看>>
(五)Git--分支管理
查看>>
(四)Git--远程仓库
查看>>
(六) Git--标签管理
查看>>
java中继承,子类是否继承父类的构造函数
查看>>
什么是Spring Cloud ?
查看>>
Qt下D-Bus的具体运用(软键盘输入法的实现)
查看>>
嵌入式环境的搭建(用于Arm开发板)
查看>>
Qt中文件读取的几种方式
查看>>
pyqt实现界面化编程
查看>>
qt写DLL文件并调用和出现的问题分析
查看>>
工厂模式(Factory)-设计模式(一)
查看>>