java抢红包功能实现
2015-11-29 20:08
513 查看
这两天做了一个抢红包功能,收藏了一个不错的生成红包的算法,分享给大家
好啦,代码就这么多,需要的参数有总金额,红包个数,单个红包最大值最小值
生成的红包按照正态分布排列的,中等金额的红包个数最多,大红包小红包较少
static Random random = new Random(); static { random.setSeed(System.currentTimeMillis()); }
public void hb() { // 金额,个数,最少值 int total = 10000; int num = 25; int min = 100; for (int i = 1; i < num; i++) { int safe_total = (total - (num - i) * min) / (num - i); int money = (int) (Math.random() * (safe_total - min) + min); total = total - money; ioService.setRedPacket(money); System.out .println("第" + i + "个红包:" + money + ",余额为:" + total + "元"); } ioService.setRedPacket(total); System.out.println("第" + num + "个红包:" + total + ",余额为:0元"); }
/** * 生产min和max之间的随机数,但是概率不是平均的,从min到max方向概率逐渐加大。 * 先平方,然后产生一个平方值范围内的随机数,再开方,这样就产生了一种“膨胀”再“收缩”的效果。 * @param min * @param max * @return */ static long xRandom(long min, long max) { return sqrt(nextLong(sqr(max - min))); }
/** * @param total 红包总额 * @param count 红包个数 * @param max 每个小红包的最大额 * @param min 每个小红包的最小额 * @return 存放生成的每个小红包的值的数组 */ public static long[] generate(long total, int count, long max, long min) { long[] result = new long[count]; long average = total / count; long a = average - min; long b = max - min; // // 这样的随机数的概率实际改变了,产生大数的可能性要比产生小数的概率要小。 // 这样就实现了大部分红包的值在平均数附近。大红包和小红包比较少。 long range1 = sqr(average - min); long range2 = sqr(max - average); for (int i = 0; i < result.length; i++) { // 因为小红包的数量通常是要比大红包的数量要多的,因为这里的概率要调换过来。 // 当随机数>平均值,则产生小红包 // 当随机数<平均值,则产生大红包 if (nextLong(min, max) > average) { // 在平均线上减钱 // long temp = min + sqrt(nextLong(range1)); long temp = min + xRandom(min, average); result[i] = temp; total -= temp; } else { // 在平均线上加钱 // long temp = max - sqrt(nextLong(range2)); long temp = max - xRandom(average, max); result[i] = temp; total -= temp; } } // 如果还有余钱,则尝试加到小红包里,如果加不进去,则尝试下一个。 while (total > 0) { for (int i = 0; i < result.length; i++) { if (total > 0 && result[i] < max) { result[i]++; total--; } } } // 如果钱是负数了,还得从已生成的小红包中抽取回来 while (total < 0) { for (int i = 0; i < result.length; i++) { if (total < 0 && result[i] > min) { result[i]--; total++; } } } return result; }
static long sqrt(long n) { // 改进为查表? return (long) Math.sqrt(n); } static long sqr(long n) { // 查表快,还是直接算快? return n * n; } static long nextLong(long n) { return random.nextInt((int) n); } static long nextLong(long min, long max) { return random.nextInt((int) (max - min + 1)) + min; }
好啦,代码就这么多,需要的参数有总金额,红包个数,单个红包最大值最小值
生成的红包按照正态分布排列的,中等金额的红包个数最多,大红包小红包较少
相关文章推荐
- Java集合中TreeSet的实现原理
- Java移位运算符详解实例——左移位运算符>>、带符号的右移位运算符>>
- 如何快速从Eclipse转向IDEA
- JAVA基本语言、语法基础(二)未完成
- Java并发编程系列之一:并发机制的底层原理
- JAVA基本语言、语法基础(一)
- Java集合中HashSet的实现原理
- Spring MVC设置首页,403,404,500页面
- Java设计模式四: 原型模式(Prototype Pattern)
- (spring-第12回【IoC基础篇】)JavaBean的属性编辑器
- Java集合之Map
- java用户角色权限数据库设计
- Struts2的404/500完全捕捉
- 使用SpringMVC+Java mail发送HTML邮件
- 基于struts2的文件上传
- spring MVC 学习(四)---拦截器,视图解析器
- java web中几个概念的区别
- Java语法基础思维图
- ajax异步提交 springMVC处理
- Java集合中ArrayList的实现原理