抢红包算法

notice:

  • 平均红包金额不能低于0.01元
  • 对浮点数四则运算和四舍五入的处理
      1 <script>
      2     //调用方法
      3     getRedPacket(10,10);
      4 
      5     /*
      6     * @description:抢红包算法
      7     * @params {Number} money 总金额
      8     * @params {Number} num 红包总个数
      9     * @return {Number}
     10     * */
     11     function getRedPacket(money,num) {
     12         var redPacketArr = [], //记录分配的红包金额
     13             remainMoney = money, //剩余的红包金额
     14             avgMoney = doDivision(money,num); //平均分得的红包金额
     15         switch (num){
     16             case 0:
     17                 alert('红包个数不能为0');
     18                 break;
     19             case 1:
     20                 redPacketArr.push(money);
     21                 break;
     22             default:
     23                 let randomIndex = 0, //最后一个数在redPacketArr的位置
     24                     last = 0; //计算最后一个数
     25                     
     26                 if(avgMoney < 0.01){
     27                     alert('单个红包金额不低于0.01元');
     28                     return;
     29                 }
     30                 for(let i = 1; i < num; i++){ //计算总数量-1个
     31                     let random = Math.random();
     32                     let randomMoney = random*rewriteToFixed(avgMoney,4), //随机值,保留4位小数(更精确)
     33                         val = rewriteToFixed(randomMoney,2); //随机值保留2为小数(钱的单位不能低于分)
     34                     if(val != 0){
     35                         remainMoney = doSubtraction(remainMoney,val);
     36                         redPacketArr.push(val);
     37                     }else {
     38                         i--;
     39                     }
     40                 }
     41                 last = redPacketArr.reduce((x,y) => doAdditive(x,y));
     42                 randomIndex = Math.floor(Math.random()*redPacketArr.length);
     43                 redPacketArr.splice(randomIndex,0,rewriteToFixed(doSubtraction(money,last),2)); //把最大金额随机插入redPacketArr中
     44         }
     45         console.log(redPacketArr);
     46         return redPacketArr;
     47     }
     48     /*
     49     * @description:重写toFixed方法
     50     * @params {Number} value,num
     51     * @return {Number}
     52     * */
     53     function rewriteToFixed(value,num) {
     54         let str = '' + value,
     55             index = str.indexOf('.'), //小数点的位置
     56             sliIndex = index + num + 1,
     57             s1 = str.slice(0,sliIndex),
     58             nextNum = Number(str.slice(sliIndex,sliIndex + 1));
     59         if(nextNum > 5){
     60             s1 = s1.replace(/\d$/,v => Number(v)+1);
     61         }
     62         return Number(s1);
     63     }
     64     /*
     65     * @description:浮点数相加
     66     * @params {Number} n1,n2
     67     * @return {Number}
     68     * */
     69     function doAdditive(n1,n2) {
     70         let e = commonCode(n1,n2);
     71         return (n1*e + n2*e)/e;
     72     }
     73 
     74     /*
     75     * @description:浮点数相减
     76     * @params {Number} n1,n2
     77     * @return {Number}
     78     * */
     79     function doSubtraction(n1,n2) {
     80         let e = commonCode(n1,n2);
     81         return (n1*e - n2*e)/e;
     82     }
     83 
     84     /*
     85     * @description:浮点数相乘
     86     * @params {Number} n1,n2
     87     * @return {Number}
     88     * */
     89     function doMultiplication(n1,n2) {
     90         let e = commonCode(n1,n2);
     91         return (n1*e) * (n2*e) / Math.pow(e,2);
     92     }
     93 
     94     /*
     95     * @description:浮点数相除
     96     * @params {Number} n1,n2
     97     * @return {Number}
     98     * */
     99     function doDivision(n1,n2) {
    100         let e = commonCode(n1,n2);
    101         return (n1*e) / (n2*e);
    102     }
    103 
    104     /*
    105     * @description:公共代码
    106     * @params {Number} n1,n2
    107     * @return {Number} e 将n1和n2带小数带转成整型
    108     * */
    109     function commonCode(n1,n2) {
    110         let len1 = 0,
    111             len2 = 0,
    112             str1 = ('' + n1),
    113             str2 = ('' + n2);
    114         if(/\./g.test(str1)){
    115             len1 = str1.split('.')[1].length; //n1小数长度 //toString()或String()用于小数后不超过7位
    116         }
    117         if(/\./g.test(str2)){
    118             len2 = str2.split('.')[1].length; //n2小数长度
    119         }
    120         return Math.pow(10,Math.max(len1,len2));
    121     }
    122 </script>

     

posted @ 2018-03-12 18:31  陈小哇  阅读(239)  评论(0)    收藏  举报