策略模式实现红包分配算法

桃李春风一杯酒,江湖夜雨十年灯。

1 前言

在前文中已经分享了模板和策略模式的实践SpringBoot-策略和模板模式的思考与实践,在本文中将结合红包算法的场景再次进行实践,主要还是分享红包计算的思考逻辑和心得。在前文中已经介绍了订单拆分的算法,红包的算法和订单的算法有相似的地方。

2 业务分析

对于红包,大家能想到的一定是抢红包的场景,因为这个是一个并发场景且是领取红包的场景,考察的知识点比较多,但是这里介绍的红包业务是需要全面覆盖的,需要从发红包开始,至于红包的领取,会在后续的文章来分享。红包的类型可以分为个人红包和群红包(群红包可以分为平分模式和拼手气模式),在本文中将着重介绍拼手气红包的分配算法。

对于平分模式的红包比较简单,采用算术评分是即可,在 java 中会出现除不尽的情况即尾差的问题,则需要使用减法来处理最后一个数据。

对于拼手气模式的红包,相对来说比较复杂一点,既要保证红包分配的均匀性,也要考虑到红包之间的差异,还有一个红包最小金额的问题。假设需要发 n 个红包,在计算第 i 个红包的随机金额时,随机数的范围最小值即红包的最小金额,最大金额的设置要保证至少有 (n - i) 个红包最小金额。即便是如此,也不能保证一次循环就可以得到所有的红包金额,所以还需要设置本次要分的最大金额要小于未分配金额的 m 倍,这样才可以保证一次循环分配所有的红包金额。

css 复制代码
# 假设需要分配 n 个红包红包分配总金额为 m ,红包分配的最小金额为 0.1 ,则每次分配的最小金额为 0.01
第i次要分配的红包金额随机数取数范围为
amt = [0.01,(m -p - 0.01*(n-i)) * 0.66]
p 为第 i 次已经分配的红包总金额
如果本次分配最大金额为剩余待分配金额的 k 倍,则系数为 k/(k +1 ), 0.66 即表示2倍,倍数越大,红包的极值差越大,否则就越小

3 红包算法

红包平分模式的算法比较简单,需要按照比例来计算每个红包的金额,在 java 编程中但凡涉及到除法,都会存在除不尽的情况,所以最后一个一定要使用减法,才能保证子单和主单的金额一致性

3.1 红包平分算法

红包平均算法就是使用算术平均方法,在 java 中对于四则运算中的除法需要考虑结果的保留位数,否则遇到除不尽的情况会报 Invalid rounding mode 的错误。最后一个红包需要使用减法来计算,否则单个红包的累计之和红包总金额不一致。在操作计算时,可以使用 hutools 中的 Numutils 工具类进行计算,可以很方便的实现计算。

3.2 拼手气算法

红包拼手气的算法如下图所示,核心的逻辑还是计算每个红包的具体金额,保证每个红包的差异性,也要保证红包间的均衡性。这里使用的是 N 倍余额算法。在计算过程中可以使用 Numutils 工具类实现便捷计算。

7 总结

在本文中,主要介绍了发红包的类型和红包算法的实现,在后续文章中将使用策略模式来实现红包的发放和领取,通过红包的业务增强了对订单金额计算深刻的认知,也拓展巩固了作者的业务理解,同时也对设计模式有了新的感悟和心得。项目 github 地址 springboot-auth

相关推荐
chenziang126 分钟前
leetcode hot100 环形链表2
算法·leetcode·链表
Captain823Jack2 小时前
nlp新词发现——浅析 TF·IDF
人工智能·python·深度学习·神经网络·算法·自然语言处理
Captain823Jack2 小时前
w04_nlp大模型训练·中文分词
人工智能·python·深度学习·神经网络·算法·自然语言处理·中文分词
刘大辉在路上3 小时前
突发!!!GitLab停止为中国大陆、港澳地区提供服务,60天内需迁移账号否则将被删除
git·后端·gitlab·版本管理·源代码管理
是小胡嘛3 小时前
数据结构之旅:红黑树如何驱动 Set 和 Map
数据结构·算法
m0_748255023 小时前
前端常用算法集合
前端·算法
呆呆的猫3 小时前
【LeetCode】227、基本计算器 II
算法·leetcode·职场和发展
Tisfy4 小时前
LeetCode 1705.吃苹果的最大数目:贪心(优先队列) - 清晰题解
算法·leetcode·优先队列·贪心·
余额不足121384 小时前
C语言基础十六:枚举、c语言中文件的读写操作
linux·c语言·算法
追逐时光者4 小时前
免费、简单、直观的数据库设计工具和 SQL 生成器
后端·mysql