以前很讨厌点外卖的我,最近中午经常点外卖,因为确实很方便,提前点好餐,算准时间,就可以在下班的时候吃上饭,然后省下的那些时间就可以在中午的时候多休息一下了。
点餐结束后,会有一个好友分享红包功能,虽说这个红包不能提现,但却可以抵扣点餐费用,对于经常点餐的人来说,直接用于抵扣现金确实是很大的诱惑,在点餐之后所获得的那个红包,必须要分享出去才能拆。
那么如果自己也想实现以下抢红包功能,需要说明的是,本文所描述的红包功能更多的关注与随机红包的生成,至于高并发、数据一致性等问题,本文暂未涉及,以下是本文所讨论的两个技术点:
- 不同的消费金额获取的红包总额不同,消费金额越大,红包总额就越大,红包总数也就越多;
- 假设有一天,有一种需求是,需要保证参与抢红包的人获得的红包金额在平均数附近波动,也就是尽量的服从正态分布;
本文描述的场景,所涉及到的金额以分为单位,目的是为了更好的处理随机数。总体的示意图如下:
需求重点,用户分享出去的红包总额跟消费总额成正比,可以分拆的子红包个数也与消费总额成正比。
比如:
那么我们设计出来一个实体,用于表示红包信息,以方便的配置及调整红包规则
1: public class RedPacketsInfo
2: {
3: /// <summary>
4: /// 最大消费金额
5: /// </summary>
6: public int MaxAmount { get; set; }
7:
8: /// <summary>
9: /// 最小消费金额
10: /// </summary>
11: public int MinAmount { get; set; }
12:
13: /// <summary>
14: /// 红包金额
15: /// </summary>
16: public int TotalAmount { get; set; }
17:
18: /// <summary>
19: /// 红包可被分割的数量
20: /// </summary>
21: public int RedPacketQuantity { get; set; }
22: }
红包初始化信息
1: private static List<RedPacketsInfo> GetRedPackets()
2: {
3: return new List<RedPacketsInfo>()
4: {
5: new RedPacketsInfo
6: {
7: MinAmount = 1000,
8: MaxAmount = 2000,
9: RedPacketQuantity = 5,
10: TotalAmount=1000
11: },
12: new RedPacketsInfo
13: {
14: MinAmount = 2000,
15: MaxAmount = 3000,
16: RedPacketQuantity = 5,
17: TotalAmount=1000
18: },
19: new RedPacketsInfo
20: {
21: MinAmount = 4000,
22: MaxAmount = 6000,
23: RedPacketQuantity = 5,
24: TotalAmount=1000
25: },
26: new RedPacketsInfo
27: {
28: MinAmount = 6000,
29: MaxAmount = 8000,
30: RedPacketQuantity = 5,
31: TotalAmount=1000
32: },
33: new RedPacketsInfo
34: {
35: MinAmount = 10000,
36: MaxAmount = int.MaxValue,
37: RedPacketQuantity = 5,
38: TotalAmount=1000
39: }
40: };
41: }
接下来我们就可以通过消费金额获取相应的红包信息了。
随机红包的生成可以在抢之前生成也可以在抢的过程中确定,一般而言,很多时候红包会在抢的过程中动态的实际分配,不过在本文中,红包在用户分享成功后会预先生成,主要原因是为了更好地处理处理数据,以使得数据能够服从正态分布。
以下是其流程图,其中有一段逻辑是回调功能,可能会有圈友会问,如何保证有回调以及回调是成功的,这个地方有很多种处理,比如MQ、任务调度等,此处也不做讨论
那么我们需要设计一个新的实体,以表示分享出去的红包及其生成的随机红包:
1: public class SharedRedPacket
2: {
3: /// <summary>
4: /// 分享人UserId
5: /// </summary>
6: public int SenderUserId { get; set; }
7:
8: /// <summary>
9: /// 分享时间
10: /// </summary>
11: public DateTime SendTime { get; set; }
12:
13: public List<RobbedRedPacket> RobbedRedPackets { get; set; }
14: }
15:
16: public class RobbedRedPacket
17: {
18: /// <summary>
19: /// 抢到红包的人的UserId
20: /// </summary>
21: public int UserId { get; set; }
22:
23: /// <summary>
24: /// 抢到的红包金额
25: /// </summary>
26: public int Amount { get; set; }
27:
28: /// <summary>
29: /// 抢到时间
30: /// </summary>
31: public DateTime RobbedTime { get; set; }
32: }
在实现过程中,根据用户消费金额获取相应红包,然后通过随机数,生成n-1个原始的随机数据,最后一个数据用总和减去n-1个数据的和获取到。
1: //红包随机拆分
2: Random ran = new Random();
3: List<double> randoms = new List<double>(redPacketsList.Count);
4: for (int i = 0; i < redPacketsInfo.RedPacketQuantity - 1; i++)
5: {
6: int max = (totalAmount - (redPacketsInfo.RedPacketQuantity - i)) * 1;
7: int result = ran.Next(1, max);
8: randoms.Add(result);
9: totalAmount -= result;
10: }
11: randoms.Add(totalAmount);
然后通过设置好系数,以处理数据达到服从正太分布的目的:
1: //正太分布处理
2: for (int i = 0; i < redPacketsInfo.RedPacketQuantity; i++)
3: {
4: double a = Math.Sqrt(Math.Abs(2 * Math.Log(randoms[i], Math.E)));
5: double b = Math.Cos(2 * Math.PI * randoms[i]);
6: randoms[i] = a * b * 0.3 + 1;
7: }
经过第二次处理后,得到的数据与原始数据有偏差,那么我们通过等比例方式再次处理,以确保拆分后的红包总额等于红包原始总额:
1: //生成最终的红包数据
2: double d = originalTotal / randoms.Sum();
3: SharedRedPacket sharedRedPacket = new SharedRedPacket();
4: sharedRedPacket.RobbedRedPackets = new List<RobbedRedPacket>(redPacketsList.Count);
5: for (int i = 0; i < redPacketsInfo.RedPacketQuantity - 1; i++)
6: {
7: sharedRedPacket.RobbedRedPackets.Add(new RobbedRedPacket
8: {
9: Amount = (int)Math.Round(randoms[i] * d, 0)
10: });
11: }
12: sharedRedPacket.RobbedRedPackets.Add(new RobbedRedPacket
13: {
14: Amount = originalTotal - sharedRedPacket.RobbedRedPackets.Sum(p => p.Amount)
15: });
测试效果图如下:
部分代码如下,
1: Console.WriteLine("是否分享输入Y分享成功,输入N退出");
2: string result = Console.ReadLine();
3: if (result == "Y")
4: {
5: var leftRedPacket = sharedRedPacket.RobbedRedPackets.Where(p => p.UserId <= 0).ToList();
6: var robbedRedPacket = leftRedPacket[new Random().Next(1, leftRedPacket.Count + 1)];
7: Console.WriteLine("抢到的到红包金额是:" + robbedRedPacket.Amount);
8: Console.WriteLine("-------------------------------------------------------");
9: }
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。