一个红包算法

需求

有一个红包算法,需求是总共发50000个,金额在75000元,每一个红包要求在1元到2元之间。

实现

暂时的实现没有考虑异常检查和优化,先贴代码后面再说吧。

             public static List<decimal> RandomRedPacket(int packetCount, Decimal totalBonus, Decimal minBonus, Decimal maxBonus)
        {
            Random RandomEvent = new Random();
            List<Decimal> resultList = new List<decimal>();

            for (int i = 0; i < packetCount; i++)
            {
                if (i == packetCount-1)
                {
                    resultList.Add(totalBonus);
                }
                else
                {
                    decimal thisBonus=0.00m;
                    //平均值  剩余钱除以剩余红包数的平均值
                    decimal avgBonus = totalBonus / (packetCount - i);   
                    if (avgBonus > maxBonus)
                    {
                        //随机区间为最小值到最大值之间 例如:1-2
                        thisBonus=RandomEvent.NextDecimal(minBonus, maxBonus ); 
                    }
                    else if (avgBonus < maxBonus && avgBonus>(maxBonus+minBonus)/2)
                    {
                        //随机区间为中间值到最大值之间 例如:>1.5-2
                        thisBonus = RandomEvent.NextDecimal(avgBonus, maxBonus);   
                    }
                    else
                    {
                        //随机区间为最小值到中间值之间 例如:1-<1.5
                        thisBonus = RandomEvent.NextDecimal(minBonus, avgBonus);
                    }
                    thisBonus = Math.Round(thisBonus, 2);
                    resultList.Add(thisBonus);
                    totalBonus -= thisBonus;
                }
            }
            return resultList;
        }

其中给Random类扩展了一个获取Decimal的方法:

        public static decimal NextDecimal(this Random rnd, decimal from, decimal to)
        {
            byte fromScale = new System.Data.SqlTypes.SqlDecimal(from).Scale;
            byte toScale = new System.Data.SqlTypes.SqlDecimal(to).Scale;

            byte scale = (byte)(fromScale + toScale);
            if (scale > 28)
                scale = 28;

            decimal r = new decimal(rnd.Next(), rnd.Next(), rnd.Next(), false, scale);
            if (Math.Sign(from) == Math.Sign(to) || from == 0 || to == 0)
                return decimal.Remainder(r, to - from) + from;

            bool getFromNegativeRange = (double)from + rnd.NextDouble() * ((double)to - (double)from) < 0;
            return getFromNegativeRange ? decimal.Remainder(r, -from) + from : decimal.Remainder(r, to);
        }

最终测试如下:

        static void Main(string[] args)
        {
            for (int i = 0; i < 3; i++)
            {
                List<decimal> poker = RandomRedPacket(50, 75, 1.00m, 2.00m);
                Decimal total = poker.Sum();
                Console.WriteLine("红包生成队列的总和为:" + total);
                Console.WriteLine("每一个红包都满足1-2之间的要求么:" + poker.TrueForAll(x => x >= 1 && x <= 2));
                Console.WriteLine("红包生成队列:" + string.Join(",", poker.ToArray()));
            }
            Console.ReadLine();
        }
    原文作者:TarsL
    原文地址: https://www.jianshu.com/p/f6ac4d06b3b5
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞