很多场景算红包的要求:根本问题就是指定的钱,指定的个数,红包发完,钱不剩余,最小红包1分钱,最大也需要限制。

原理:割绳子算法:每次都取最大值为总绳长的随机值,最后将其排序,计算每两个的差值,总差值即就是总绳子长度,但是割绳子算法算出来的金额可能会出现超出最大金额的值,那么就会需要使用平均算法。
平均算法(自己取的名字):将超过最大限定金额的值全部重新赋值,并将他们舍去的部分,随机分给最小的金额,并保证最小的金额加上一个值不超过最大值即可。
洗牌算法:最终要将排序的金额进行打乱。

开源是程序员的基本美德

         int pp = ;//元换算成分的比例

             int total =(int)((decimal) * pp);//红包总额
int num = ;//红包个数
int min = (int)((decimal)0.02 * pp);//红包不少于
int max = (int)((decimal) * pp);//最大红包不超过 if (min <= && min >= (total - max) / (num - ))
{
Console.WriteLine($"红包最小值异常:{total}分{num}个红包,最小值必须大于0,且不能小余{(total - max) / (num - 1)/100f}");
return;
}
if (num * min > total)
{
Console.WriteLine($"红包最小值异常:{total}分{num}个红包,红包最小值不能超过{total / num / 100f}");
return;
}
if (num * max < total)
{
Console.WriteLine($"红包最大值异常:{total}分{num}个红包,红包最大值不能小余{total / num / 100f}");
return;
}
if (max > total - min * (num - ))
{
Console.WriteLine($"红包最大值异常:{total}分{num}个红包,红包最大值不能超过{(total - min * (num - 1)) / 100f}");
return;
} float[] ret = new float[num];
ret[] = ;
int i = ;
//下面不考虑随机数的唯一性,给每个人都预留最少的钱
int totalByHundred = total - (num * min);
Random random = new Random();
while (i < num)
{
ret[i] = random.Next(totalByHundred);
i++;
}
//先从大到小排序 将差值计算出来+最先预留的min值
Array.Sort(ret);
i = ;
while (i < num - )
{
ret[i] = (ret[i + ] - ret[i] + min);//每个人都预留最少的钱
i++;
}
ret[i] = (totalByHundred - ret[i] + min);//最后一个 仍然是最大可分值-自身+min值即可。
//再次排序金额 将超出最大值的金额 全部重新赋值,并将差值累加给tempmax ,然后将tempmax再依次随机分给最小的金额
Array.Sort(ret);
float tempmax = ;
for (int k = ret.Length - ; k >= ; k--)
{
if (ret[k] > max)
{
float t = random.Next(min,max);
tempmax += ret[k] - t;
ret[k] = t;
}
else
{
break;
}
}
//分完为止 可能运气好 没有可分的
while (tempmax > )
{
Console.WriteLine("触发平均算法执行");
Array.Sort(ret);
for (int k = ; k < ret.Length; k++)
{
//一轮分不完 将再次排序再分 tempmax为0即可
if (tempmax > )
{
int tm = max - (int)ret[k];
if (tempmax< tm)
{
//此处判断非常重要
ret[k] = ret[k] + tempmax;
tempmax = ;
}
else
{
float t = random.Next(tm);
ret[k] = ret[k] + t;
tempmax -= t;
}
}
else
{
break;
}
}
} //最后利用洗牌算法进行打乱数组
int currentIndex;
float tempValue;
for (int j = ; j < ret.Length; j++)
{
currentIndex = random.Next(, ret.Length - j);
tempValue = ret[currentIndex];
ret[currentIndex] = ret[ret.Length -- j];
ret[ret.Length- - j] = tempValue;
}
//完美
for (int j = ; j < ret.Length; j++)
{
Console.WriteLine($"第{j + 1}个红包:金额{(ret[j] / 100f)}元");
}
//最后检查总红包金额以及最大最小红包是否符合要求 肯定符合要求的 只是输出看一下
Console.WriteLine($"红包总金额:{(ret.Sum() / 100f).ToString("F2")}元,红包最大值:{ret.Max() / 100f}元,红包最小值:{ret.Min() / 100f}元");

该算法由C#写成,更多交流请关注原文博客地址:

红包算法的一种

 

.NET C# 红包生成算法,可设置红包总额和数量,可限制最大最小红包的更多相关文章

  1. PHP用抛物线的模型实现微信红包生成算法的程序源码

    <?php /* *Author:Kermit *Time:2015-8-26 *Note:红包生成随机算法 */ header("Content-type:text/html;cha ...

  2. PHP微信红包生成算法的程序源码(用抛物线的模型实现)

    代码如下: <?php /* * 红包生成随机算法 */ header("Content-type:text/html;charset=utf-8"); date_defau ...

  3. php红包生成随机算法

    一.适用场景 红包总金额X,分配成Y个红包,每个红包随机金额. 二.生成算法 /** * 红包生成算法 * @param $money 总金额 * @param $number 红包数量 * @par ...

  4. 微信红包随机生成算法(PHP版)

    /** * 求一个数的平方 * @param $n */ function sqr($n){ return $n*$n; } /** * 生产min和max之间的随机数,但是概率不是平均的,从min到 ...

  5. java实现微信红包分配算法

    红包算法分析 有人认为,抢红包的额度是从0.01到剩余平均值*N(N是一个系数,决定最大的红包值)之间,比如一共发了10块钱,发了10个红包:第一个人可以拿到(0.01~1*N)之间的一个红包值,当然 ...

  6. 研究微信红包分配算法之Golang版

    今天来看一下红包的分配,参考几年前流传的微信红包分配算法,今天用Golang实现一版,并测试验证结果. 微信红包的随机算法是怎样实现的?https://www.zhihu.com/question/2 ...

  7. java使用BigDecimal 实现随机金额红包拆分算法

    原创代码,引用注明出处:https://www.cnblogs.com/guangxiang/p/12218714.html @Servicepublic class SplitRedPacketsS ...

  8. PHP微信红包的算法实现探讨

    header("Content-Type: text/html;charset=utf-8");//输出不乱码,你懂的 $total=10;//红包总额 $num=8;// 分成8 ...

  9. RocketMQ msgId生成算法

    当我们用RocketMQ发送信息的时候通常都会返回如下信息: SendResult [sendStatus=SEND_OK, msgId=0A42333A0DC818B4AAC246C290FD000 ...

随机推荐

  1. pytorch adam 源码 关于优化函数的调整 optimizer 调参 重点

    关于优化函数的调整拆下包:https://ptorch.com/docs/1/optim class torch.optim.Optimizer(params, defaults)所有优化的基类. 参 ...

  2. JS拉平数组

    JS拉平数组 有时候会遇到一个数组里边有多个数组的情况(多维数组),然后你想把它拉平使其成为一个一维数组,其实最简单的一个方法就是ES6数组方法Array.prototype.flat.使用方法如下: ...

  3. poj 3181 Dollar Dayz(完全背包)

    Dollar Dayz Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5419   Accepted: 2054 Descr ...

  4. H3C 配置高级ACL

  5. [转]Jquery属性选择器(同时匹配多个条件,与或非)(附样例)

    1. 前言 为了处理除了两项不符合条件外的选择,需要用到jquery选择器的多个条件匹配来处理,然后整理了一下相关的与或非的条件及其组合. 作为笔记记录. 2. 代码 1 2 3 4 5 6 7 8 ...

  6. 脑残的设计--- 视图(view)里面包含order by

    2015/05/26 更新 今天又遇到了类似问题...尼玛无语了 编码规范啊 !!! 今天有个兄弟跟我说sql跑得太慢了,让我看看.sql如下: SELECT rownum row_num, pv.v ...

  7. [转]Redis和Memcache区别,优缺点对比

    1. Redis和Memcache都是将数据存放在内存中,都是内存数据库.不过memcache还可用于缓存其他东西,例如图片.视频等等. 2.Redis不仅仅支持简单的k/v类型的数据,同时还提供li ...

  8. Python--day38--进程同步控制的---锁\信号量\事件的方法名

  9. java 基本数据类型的自动拆箱与装箱

    ——>  -128~127之间的特殊性.为什么要这样设计,好处? ——>  享元模式(Flyweight Pattern):享元模式的特点是,复用我们内存中已存在的对象,降低系统创建对象实 ...

  10. PHP性能监控

    使用xhprof进行线上PHP性能追踪及分析 日志未经声明,均为AlloVince原创.版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可. 之前一直使用基于Xdebug进行PHP的性 ...