加入收藏 | 设为首页 | 会员中心 | 我要投稿 许昌站长网 (https://www.0374zz.cn/)- 专属主机、负载均衡、智能边缘云、云防火墙、数据加密!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

JavaScript指定红包金额的算法怎样实现?

发布时间:2022-02-19 13:43:54 所属栏目:语言 来源:互联网
导读:今天给大家分享一个比较有趣的实例,相信很多朋友都有抢过微信红包吧,有的人红包抢到的金额的多,有的人抢到的少,那么大家是否有好奇这是怎样实现的,下面小编就给大家介绍一下用JavaScript实现指定红包金额的算法,感兴趣的朋友就继续往下看吧。 实现需求
       今天给大家分享一个比较有趣的实例,相信很多朋友都有抢过微信红包吧,有的人红包抢到的金额的多,有的人抢到的少,那么大家是否有好奇这是怎样实现的,下面小编就给大家介绍一下用JavaScript实现指定红包金额的算法,感兴趣的朋友就继续往下看吧。
 
      实现需求如下
单个包最小金额为0.01
如果除指定金额外,其余都为0.01,最后尾包存在为0的几率
本算法通过了1000000次测试,出错率为百万分之3
    效果展示
 
 
    空包问题
 
 
    红包算法
/*
    param: float, int, int, float
    param1:红包金额总额
    param2:红包数目
    param3:指定特殊红包
    param4:指定特殊红包金额
 */
let getPrize = function(total, number, index, volume){
    let allowance = total - volume;
 
    let arr = [];
    let i = 0;
    while(i < number - 2){
        // 指定[0.01,allowance-(i*0.01))
        let temp = (Math.random()*(allowance - (number - 1 - i) * 0.01) + 0.01).toFixed(2);
        // if(temp < 0)    console.log(`temp:${temp}`);
        temp = temp <= 0 ? 0.01 : temp;        
        arr.push(parseFloat(temp));
        allowance = parseFloat((allowance - temp).toFixed(2));        
        i++;
        // console.log(`arr:${arr}, i:${i}`);
        // 如果出现小于0的分配情况,剥削强者均分
        if(allowance <= 0){
            // console.log(`alowance:${allowance}`);
            
            
            let w = arr.filter((val,index)=>{
                // console.log(`val:${val}`);
                if(val > 0.01){
                    
                    arr[index] = parseFloat((arr[index] - 0.01).toFixed(2));
                    return val;
                }
            });
 
            if(w.length == 0){
                allowance = 0;
            }else{
                allowance = 0.01;
            }
            
        }
    }
    // 最后一个放入
    arr.push(parseFloat(allowance.toFixed(2)));
    let result = arr;
 
    return result.slice(0, index).concat(parseFloat(volume), result.slice(index));
}
    测试样例
 
// Test sample
for(let m = 0; m < 10000; m++){
    let total = (Math.random()*100 + 0.01).toFixed(2);
 
    let number = Math.floor(Math.random()*20 +2);
    while(total / number < 0.01){
        number = Math.floor(Math.random()*20 +2);
    }
 
    let index = Math.floor(Math.random()*(number - 1));
 
    let volume = (Math.random()*(total - 0.01*(number-1))+0.01).toFixed(2);
    while(volume >= total || volume + 0.01*(number-1) > total){
        // console.log(`xx:${volume}`);
        volume = (Math.random()*(total - 0.01*(number-1))+0.01).toFixed(2);
        volume = volume <= 0 ? 0.01 : volume;
    }
    
    
    let test = getPrize(total, number, index, volume);
    // console.log(test);
    let sum  = test.reduce((total,val)=>total+=parseFloat(val));
    sum = sum.toFixed(2);
    if(sum !== total) {
        console.log(`volume:${volume}, total: ${total}, number: ${number}`);
        console.log(`sum:${sum}`);
        console.log(test);
    }
    test.map((val,index)=>{
        if(val <= 0 && index !== test.length - 1){
            console.log(`volume:${volume}, total: ${total}, number: ${number}`);
            console.log(`sum:${sum}`);
            console.log(test);
        }
    });
 
}

(编辑:许昌站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读