求一個紅包算法

m個硬幣,n個紅包,紅包裏的硬幣數不能夠小於b,也不能夠大於t,數目是隨機的。html

mnt均爲天然數,且 n*b<=m<=n*t。算法

求紅包算法dom

function getRedPackets(m,n,b,t){測試

         var ret = new Array(n);spa

         /*todo*/.net

         return ret;code

}htm

示例代碼 http://wagang.net/hongbao.htmlblog

<!doctype html>
<html>
 <head>
  <meta charset="UTF-8">
  <title>紅包算法--JK</title>
 </head>
 <body>

m個硬幣,n個紅包,紅包裏的硬幣數不能夠小於b,也不能夠大於t,數目是隨機的。<br>
mnt均爲天然數,且 n*b<=m<=n*t。
<hr><input id=m value=100 style="width:50px">個硬幣,<input id=n value=10 style="width:50px">個包,每人最少<input id=b value=1 style="width:50px">,最多<input id=t value=100 style="width:50px"> <input type=button value="生成紅包" onclick="生成紅包()"> <input type=button value="分析數據" onclick="分析數據()"> <input type=button value="清空數據" onclick="清空數據()"><hr>
<textarea id=result style="width:800px;height:300px;"></textarea>
<script>

function g(id){
    return document.getElementById(id);
}


function getRedPackets(m,n,b,t){ //
    /* 代碼思路:
     * 每次生成一個紅包k,k需知足如下條件:
     * b <= k <=t  而且 (n-1)*b <= m-k <= (n-1)*t;
     * 因此,k的取值範圍是[Math.max(b, m-(n-1)*t),Math.min(t,m-(n-1)*b)];
    */
    var ret = [];
    while(n>1){
        n--;
        var kMin = Math.max(b, m-n*t),
            kMax = Math.min(t,m-n*b),
            kAvg = m/(n+1),
            kDis = Math.min(kAvg - kMin,kMax - kAvg);
        var k = Math.round(kAvg+ 2*(Math.random()-0.5)*kDis); //本句使用平均分佈,待改進。目前寫法致使:1紅包分佈域不夠寬,2後取的紅包方差大。
        m -= k;
        ret.push(k);
    }
    ret.push(m);
    return ret;
}

//如下爲測試代碼,請忽不用改
function 生成紅包(){
    var m=g('m').value,
        n=g('n').value,
        b=g('b').value,
        t=g('t').value;

    if((m|0)!=m || (n|0)!=n || (b|0)!=b || (t|0)!=t) return alert('請檢查您的輸入');
    if(n*b>m*1 || n*t<m*1) return alert('不符合「n*b<=m<=n*t」');
    var ret = getRedPackets(m,n,b,t),
        total=0;
    for(var i=0;i<ret.length;i++){
        total += ret[i];
    }    
    g('result').value += getRedPackets(m,n,b,t).join('\t')+'\t'+total+'\n';
}

function 分析數據(){
    var data = g('result').value.replace(/\s+$/g,'').split(/[\r\n]+/);
    for(var i=0;i<data.length;i++) {
        data[i] = data[i].split(/\t/);
        if(data[i].length != data[0].length){
            return alert('數據不統一,沒法分析,建議清空數據從新生成再分析');
        }
    }
    if (data.length<2){
        return alert('數據過小,沒法分析');
    }
    var avg = [],
        delta = []
        luck = [];

    for(var j=0;j<data[0].length;j++){
        avg[j] = 0;
        delta[j] = 0;
        luck[j] = 0;
    }
    for(var i=0;i<data.length;i++) {
        var tempLuck=0,
            max = data[i][0];
        for(var j = 0;j<data[i].length;j++){
            avg[j] += (data[i][j]|0);
            if(data[i][j]>max){
                max=data[i][j];
                tempLuck = j;
            }
        }
        luck[tempLuck]++;
    }
    for(var j = 0;j<avg.length;j++){
        avg[j] = avg[j]/data.length;
    }

    for(var i=0;i<data.length;i++) {
        for(var j = 0;j<data[i].length;j++){
            delta[j] += Math.pow((data[i][j]-avg[j]),2);
        }
    }
    for(var j = 0;j<avg.length;j++){
        delta[j] = Math.pow(delta[j]/data.length,0.5);
    }

    for(var j = 0;j<avg.length;j++){
        avg[j] = avg[j].toFixed(2);
        delta[j] = delta[j].toFixed(2);
    }

    g('result').value += avg.join('\t')+'\t平均值\n';
    g('result').value += delta.join('\t')+'\t方差值\n';
    g('result').value += luck.join('\t')+'\t最佳手氣\n';

}

function 清空數據(){
    g('result').value ='';

}
</script>
 </body>
</html>
相關文章
相關標籤/搜索